请问谁用过stm32驱动ds12c887这个实时时钟芯片?

2019-08-13 22:50发布

RT,本人按照那个RTC的时序来写的程序,死活读不了时钟的数据,网上基本上全是51驱动的这个芯片,不知道哪位用stm32驱动过这个片子,求解答!!!以下是本人写的读写函数
//写DS12C887函数
void write_ds(unsigned char add,unsigned char date)
{
  dscs = 0;
  dsas = 0;
  dsds = 1;
  dsrw = 1;  
  wad0 = (add & 0x01); //先写地址 
  wad1 = ((add & 0x02) >>1);
  wad2 = ((add & 0x04) >>2);
  wad3 = ((add & 0x08) >>3);
  wad4 = ((add & 0x10) >>4);
  wad5 = ((add & 0x20) >>5);
  wad6 = ((add & 0x40) >>6);
  wad7 = ((add & 0x80) >>7);  
  dsas = 1;
  dsrw = 0;
  wad0 = (date & 0x01); //再写数据
  wad1 = ((date & 0x02) >>1);
  wad2 = ((date & 0x04) >>2);
  wad3 = ((date & 0x08) >>3);
  wad4 = ((date & 0x10) >>4);
  wad5 = ((date & 0x20) >>5);
  wad6 = ((date & 0x40) >>6);
  wad7 = ((date & 0x80) >>7);
  dsrw = 1;
  dsas = 0;
  dscs = 1;
}

//读DS12C887函数
unsigned char read_ds(unsigned char add)
{
  unsigned char ds_date;
  unsigned char d1;
  unsigned char d2;
  unsigned char d3;
  unsigned char d4;
  unsigned char d5;
  unsigned char d6;
  unsigned char d7;
  unsigned char d8;
  dscs = 0;
  dsas = 0;
  dsds = 1;
  dsrw = 1;
  wad0 = (add & 0x01); //先写地址 
  wad1 = ((add & 0x02) >>1);
  wad2 = ((add & 0x04) >>2);
  wad3 = ((add & 0x08) >>3);
  wad4 = ((add & 0x10) >>4);
  wad5 = ((add & 0x20) >>5);
  wad6 = ((add & 0x40) >>6);
  wad7 = ((add & 0x80) >>7);  
  dsas = 1;
  dsds = 0;
  d1 = (rad7 << 7);
  d2 = (rad6 << 6);
  d3 = (rad5 << 5);
  d4 = (rad4 << 4);
  d5 = (rad3 << 3);
  d6 = (rad2 << 2);
  d7 = (rad1 << 1);
  d8 = rad0 ;
  ds_date = (d1 + d2 + d3 + d4 + d5 + d6 + d7 + d8);//再读数据
  dsds = 1;
  dsas = 0;
  dscs = 1;
  return ds_date;
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
13条回答
zlk1214
1楼-- · 2019-08-14 00:18
用FSMC接口就行了。不过PB7上需要接74HC04反相器后才能与AS脚连接。
单片机:STM32F103VET6
[mw_shl_code=c,true]#include <stdio.h>
#include <stm32f10x.h>
#include <string.h>

typedef __packed struct
{
        __IO uint8_t SEC;
        __IO uint8_t SECALR;
        __IO uint8_t MIN;
        __IO uint8_t MINALR;
        __IO uint8_t HOUR;
        __IO uint8_t HOURALR;
        __IO uint8_t DAY;
        __IO uint8_t DATE;
        __IO uint8_t MONTH;
        __IO uint8_t YEAR;
        __IO uint8_t CR1;
        __IO uint8_t CR2;
        __IO uint8_t CR3;
        __IO uint8_t CR4;
        __IO uint8_t RAM1[36]; // 0x0e-0x31
        __IO uint8_t CENTURY;
        __IO uint8_t RAM2[77]; // 0x33-0x7f
} DS12C887_TypeDef;

#define RTC2 ((DS12C887_TypeDef *)0x60000000)

// 延时n毫秒
void delay(uint16_t nms)
{
        TIM_TimeBaseInitTypeDef tim;
        TIM_TimeBaseStructInit(&tim);
        tim.TIM_Period = 10 * nms - 1;
        tim.TIM_Prescaler = 7199;
        TIM_TimeBaseInit(TIM6, &tim);
        TIM_ClearFlag(TIM6, TIM_FLAG_Update);
        TIM_SelectOnePulseMode(TIM6, TIM_OPMode_Single);
        TIM_Cmd(TIM6, ENABLE);
        while (TIM_GetFlagStatus(TIM6, TIM_FLAG_Update) == RESET);
}

int fputc(int ch, FILE *fp)
{
        if (fp == stdout)
        {
                if (ch == ' ')
                {
                        while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
                        USART_SendData(USART1, ' ');
                }
                while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
                USART_SendData(USART1, ch);
        }
        return ch;
}

int main(void)
{
        FSMC_NORSRAMInitTypeDef fsmc;
        FSMC_NORSRAMTimingInitTypeDef fsmc_timing;
        GPIO_InitTypeDef gpio;
        USART_InitTypeDef usart;
        
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_USART1, ENABLE);
        
        // PA8为RST复位引脚(默认输出低电平)
        gpio.GPIO_Mode = GPIO_Mode_Out_PP;
        gpio.GPIO_Pin = GPIO_Pin_8;
        gpio.GPIO_Speed = GPIO_Speed_2MHz;
        GPIO_Init(GPIOA, &gpio);
        
        // PA9为串口1发送引脚
        gpio.GPIO_Mode = GPIO_Mode_AF_PP;
        gpio.GPIO_Pin = GPIO_Pin_9;
        gpio.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA, &gpio);
        
        // PB7为NADV, 取反后送到AS引脚上, 该引脚不可用地址线代替
        gpio.GPIO_Pin = GPIO_Pin_7;
        GPIO_Init(GPIOB, &gpio);
        
        // PD0~1为AD2~3, PD4为NOE接DS引脚, PD5为NWE接RW引脚, PD7为NE1片选引脚接CS, PD14~15为AD0~1
        gpio.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_7 | GPIO_Pin_14 | GPIO_Pin_15;
        GPIO_Init(GPIOD, &gpio);
        
        // PE7~10为AD4~7
        gpio.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10;
        GPIO_Init(GPIOE, &gpio);
        
        // 初始化串口1
        USART_StructInit(&usart);
        usart.USART_BaudRate = 115200;
        usart.USART_Mode = USART_Mode_Tx;
        USART_Init(USART1, &usart);
        USART_Cmd(USART1, ENABLE);
        
        // FSMC的Bank1, Subbank1设为8位NOR Flash地址/数据线复用模式, 关闭NWAIT引脚
        fsmc.FSMC_ReadWriteTimingStruct = &fsmc_timing;
        fsmc.FSMC_WriteTimingStruct = &fsmc_timing;
        FSMC_NORSRAMStructInit(&fsmc);
        fsmc.FSMC_MemoryType = FSMC_MemoryType_NOR; // 存储器类型为NOR Flash
        fsmc.FSMC_WaitSignal = FSMC_WaitSignal_Disable; // 不使用NWAIT引脚
        fsmc_timing.FSMC_AddressHoldTime = 1;
        fsmc_timing.FSMC_AddressSetupTime = 0;
        fsmc_timing.FSMC_BusTurnAroundDuration = 0;
        fsmc_timing.FSMC_DataSetupTime = 2; // HCLK=72MHz时, DATAST的最小值为2, 即3xHCLK clock cycles
        FSMC_NORSRAMInit(&fsmc);
        FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM1, ENABLE); // 虽然Subbank1默认是启用的, 但执行FSMC_NORSRAMInit函数时会被关闭, 所以需要再次开启
        
        printf("STM32F103VE FSMC DS12C887 ");
        delay(200);
        GPIO_WriteBit(GPIOA, GPIO_Pin_8, Bit_SET); // RESET=1, 撤销复位信号
        
        // 读写自由SRAM区域
        printf("General-purpose RAM1 addr: 0x%08x ", (uint32_t)RTC2->RAM1);
        printf("General-purpose RAM2 addr: 0x%08x ", (uint32_t)RTC2->RAM2);
        strcpy((char *)RTC2->RAM1, "Flexible static memory controller");
        strcpy((char *)RTC2->RAM2, "Muxed mode - multiplexed asynchronous access to NOR Flash memory");
        printf("str1=%s ", RTC2->RAM1);
        printf("str2=%s ", RTC2->RAM2);
        
        // 读A~D寄存器
        printf("A=0x%02x B=0x%02x C=0x%02x D=0x%02x ", RTC2->CR1, RTC2->CR2, RTC2->CR3, RTC2->CR4);
        while (1)
                __WFI();
}

void HardFault_Handler(void)
{
        printf("Hard Error! ");
        while (1);
}[/mw_shl_code]
huidefengsy
2楼-- · 2019-08-14 03:20
在线等,在线等
huidefengsy
3楼-- · 2019-08-14 04:34
是不是这个片子太古老了,没人用过。。。
正点原子
4楼-- · 2019-08-14 05:22
 精彩回答 2  元偷偷看……
huidefengsy
5楼-- · 2019-08-14 10:40
回复【4楼】正点原子:
---------------------------------
原子哥用过这个时钟芯片吗?
Director_Liu
6楼-- · 2019-08-14 12:27
在郭天祥51的教程中见过,但没用过。

一周热门 更多>