STM32的开发板上有个DS1302芯片,STM32从DS1302上读取时间,并通过串口通讯显示在PC的串口调试助手上。
STM32和DS1302的接线如下:
代码如下:
#include "stm32f10x.h"
#include <stdio.h>
#include <string.h>
#define AHB_INPUT 72
#define DS1302_PORT GPIOB
#define DS1302_SCK_PIN GPIO_Pin_5
#define DS1302_IO_PIN GPIO_Pin_6
#define DS1302_CE_PIN GPIO_Pin_7
u8 WRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};
u8 TIME[7] = {0, 0x30, 0x17, 0x02, 0x05, 0x01, 0x19};
void delay_us(uint32_t time_us)
{
SysTick->LOAD = AHB_INPUT * time_us;
SysTick->VAL = 0x00;
SysTick->CTRL = 0x00000005;
for(;!(SysTick->CTRL & 0x00010000););
SysTick->CTRL = 0x00000004;
}
void delay_ms(uint32_t time_ms)
{
for(;time_ms-- > 0;)
{
delay_us(1000);
}
}
void usart1_init(uint32_t bound)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB1Periph_USART2 | RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_InitStructure.USART_BaudRate = bound;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART2, &USART_InitStructure);
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
USART_Cmd(USART2, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_ResetBits(GPIOA, GPIO_Pin_1);
}
void RCC_Configuration(void)
{
RCC_DeInit();
RCC_HSEConfig(RCC_HSE_ON);
while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //Enable Prefetch Buffer
FLASH_SetLatency(FLASH_Latency_2); //Flash 2 wait state
RCC_HCLKConfig(RCC_SYSCLK_Div1); //HCLK = SYSCLK
RCC_PCLK2Config(RCC_HCLK_Div1); //PCLK2 = HCLK
RCC_PCLK1Config(RCC_HCLK_Div2); //PCLK1 = HCLK/2
RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9); //PLLCLK = 8MHZ * 9 =72MHZ
RCC_PLLCmd(ENABLE); //Enable PLLCLK
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET){};
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //Select PLL as system clock
while(RCC_GetSYSCLKSource()!=0x08); //Wait till PLL is used as system clock source
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
}
void RS485_Config(u32 bound)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* config USART1 clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2 , ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);
/* USART1 GPIO config */
/* Configure USART1 Tx (PA.02) as alternate function push-pull *///TX
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure USART1 Rx (PA.03) as input floating *///RX
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = bound;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No ;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART2, &USART_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
USART_Cmd(USART2, ENABLE);
//USART_ClearFlag(USART1, USART_FLAG_TC);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_SetBits(GPIOA, GPIO_Pin_1);
}
void func_ds1302_configuration()
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStruct.GPIO_Pin = DS1302_SCK_PIN | DS1302_CE_PIN ;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(DS1302_PORT, &GPIO_InitStruct);
}
void func_config_ds1302_io_pin(u8 in_out)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(in_out == 1)
{
GPIO_InitStruct.GPIO_Pin = DS1302_IO_PIN;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(DS1302_PORT, &GPIO_InitStruct);
}
else
{
GPIO_InitStruct.GPIO_Pin = DS1302_IO_PIN;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(DS1302_PORT, &GPIO_InitStruct);
}
}
void nop(u8 nop_cnt)
{
for(;nop_cnt-- > 0;)
{
__NOP();
}
}
void func_write_ds1302_a_byte(u8 addr, u8 dat)
{
u8 n;
GPIO_ResetBits(DS1302_PORT, DS1302_CE_PIN);
nop(2);
GPIO_ResetBits(DS1302_PORT, DS1302_SCK_PIN);
nop(2);
GPIO_SetBits(DS1302_PORT, DS1302_CE_PIN);
nop(2);
func_config_ds1302_io_pin(1);
nop(2);
for (n=0; n<8; n++)
{
GPIO_WriteBit(DS1302_PORT, DS1302_IO_PIN, (BitAction)(0x01 & addr));
addr >>= 1;
GPIO_SetBits(DS1302_PORT, DS1302_SCK_PIN);
nop(2);
GPIO_ResetBits(DS1302_PORT, DS1302_SCK_PIN);
nop(2);
}
for (n=0; n<8; n++)
{
GPIO_WriteBit(DS1302_PORT, DS1302_IO_PIN, (BitAction)(0x01 & dat));
dat >>= 1;
GPIO_SetBits(DS1302_PORT, DS1302_SCK_PIN);
nop(2);
GPIO_ResetBits(DS1302_PORT, DS1302_SCK_PIN);
nop(2);
}
GPIO_ResetBits(DS1302_PORT, DS1302_CE_PIN);
nop(2);
}
/**
* CLOCK - SEC : 0x81
* CLOCK - MIN : 0x83
* CLOCK - HR : 0x85
* CLOCK - DATE : 0x87
* CLOCK - MONTH : 0x89
* CLOCK - DAY : 0x8B
* CLOCK - YEAR : 0x8D
*/
u8 func_read_ds1302_a_byte(u8 cmd)
{
u8 tmp;
u8 i;
u8 ret;
if(cmd < 0x81 || cmd > 0x8F)
{
return 255;
}
GPIO_ResetBits(DS1302_PORT, DS1302_CE_PIN);
GPIO_ResetBits(DS1302_PORT, DS1302_SCK_PIN);
func_config_ds1302_io_pin(1);
nop(5);
GPIO_SetBits(DS1302_PORT, DS1302_CE_PIN);
for(i = 0; i < 8; i++)
{
tmp = cmd;
tmp= tmp >> i;
GPIO_WriteBit(DS1302_PORT, DS1302_IO_PIN, (BitAction)(0x01 & tmp));
nop(2);
GPIO_SetBits(DS1302_PORT, DS1302_SCK_PIN);
nop(2);
GPIO_ResetBits(DS1302_PORT, DS1302_SCK_PIN);
nop(2);
}
func_config_ds1302_io_pin(0);
nop(2);
for(i = 0; i < 8; i++)
{
tmp = GPIO_ReadInputDataBit(DS1302_PORT, DS1302_IO_PIN);
ret = ret | (tmp << i);
GPIO_SetBits(DS1302_PORT, DS1302_SCK_PIN);
nop(2);
GPIO_ResetBits(DS1302_PORT, DS1302_SCK_PIN);
nop(2);
}
GPIO_ResetBits(DS1302_PORT, DS1302_CE_PIN);
nop(2);
func_config_ds1302_io_pin(1);
nop(2);
GPIO_SetBits(DS1302_PORT, DS1302_SCK_PIN);
nop(2);
GPIO_ResetBits(DS1302_PORT, DS1302_IO_PIN);
nop(2);
GPIO_SetBits(DS1302_PORT, DS1302_IO_PIN);
nop(2);
return ret;
}
u8 func_read_ds1302_time(char *ret_time)
{
u8 ret;
u8 tmp_t[14];
//YEAR
ret = func_read_ds1302_a_byte(0x8D);
if(ret == 255)
{
return 255;
}
tmp_t[1] = ret & 0x0f;
tmp_t[0] = ret >> 4;
//MONTH
ret = func_read_ds1302_a_byte(0x89);
if(ret == 255)
{
return 255;
}
tmp_t[3] = ret & 0x0f;
tmp_t[2] = ret >> 4;
//DATE
ret = func_read_ds1302_a_byte(0x87);
if(ret == 255)
{
return 255;
}
tmp_t[5] = ret & 0x0f;
tmp_t[4] = ret >> 4;
//HR
ret = func_read_ds1302_a_byte(0x85);
if(ret == 255)
{
return 255;
}
tmp_t[7] = ret & 0x0f;
tmp_t[6] = ret >> 4;
//MIN
ret = func_read_ds1302_a_byte(0x83);
if(ret == 255)
{
return 255;
}
tmp_t[9] = ret & 0x0f;
tmp_t[8] = ret >> 4;
//SEC
ret = func_read_ds1302_a_byte(0x81);
if(ret == 255)
{
return 255;
}
tmp_t[11] = ret & 0x0f;
tmp_t[10] = ret >> 4;
sprintf(ret_time, "20%d%d-%d%d-%d%d %d%d:%d%d:%d%d ", tmp_t[0], tmp_t[1], tmp_t[2], tmp_t[3], tmp_t[4], tmp_t[5], tmp_t[6], tmp_t[7], tmp_t[8], tmp_t[9], tmp_t[10], tmp_t[11]);
return 0;
}
void Ds1302Init()
{
u8 n;
func_write_ds1302_a_byte(0x8E, 0X00);
for (n=0; n<7; n++)
{
func_write_ds1302_a_byte(WRITE_RTC_ADDR[n], TIME[n]);
}
func_write_ds1302_a_byte(0x8E,0x80);
}
int main()
{
u8 i = 0;
u8 suc;
char ch_t[24];
RS485_Config(9600);
func_ds1302_configuration();
Ds1302Init();
while (1)
{
suc = func_read_ds1302_time(ch_t);
if(suc == 0)
{
for(i = 0; i < 20; i++)
{
USART_SendData(USART2, ch_t[i]);
while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET);
}
}
delay_ms(1000);
}
}
读取时间的效果如下:
测试代码,可以实现读取数据,仅供参考。