c - 将 mcp7940N 与 PIC18F24K40 接口
问题描述
我正在尝试将 PIC18F24k40 设备连接到 MCP7940 N RTC 设备。我已经为 100khz 频率配置了 8mhz 和 RTC。我已经用 arduino uno 板测试了我的硬件,它运行良好。但我使用的是 pic 微控制器,带有 mcc 生成的库。在下面的代码中,我可以显示 min=20 和 sec=10,但 sec 参数没有增加。我尝试使用 DS1307/DS3233/PC8563 RTC 设备的类似硬件效果很好,我可以使用逻辑分析仪获得 SDA/SCL 脉冲.
我不会得到以下代码的任何响应,但它会显示我正在写入 i2c 从地址的内容,
有人可以帮我弄清楚应该读取什么格式来获得 rtc min 和 second
#include "mcc_generated_files/mcc.h"
#include"mcc_generated_files/examples/i2c1_master_example.h"
int sec;
int min;
int hour;
int date;
int month;
int year;
int day;
int temp=0;
int r_data;
#define Seg1 0x01
#define Seg2 0x02
#define Seg3 0x04
#define Seg4 0x08
#define Seg5 0x10
#define Seg6 0x20
unsigned char Flag_Update=0;
void Delay(unsigned int k) {
unsigned int j;
for(j=0; j<k; j++);
}
void SetSeg(unsigned short data, unsigned short segno)
{
switch(data) {
case 0:
PORTB = 0x3F;
break;
case 1:
PORTB = 0x06;
break;
case 2:
PORTB = 0x5B;
break;
case 3:
PORTB = 0x4F;
break;
case 4:
PORTB = 0x66;
break;
case 5:
PORTB = 0x6D;
break;
case 6:
PORTB = 0x7D;
break;
case 7:
PORTB = 0x07;
break;
case 8:
PORTB = 0x7F;
break;
case 9:
PORTB = 0x6F;
break;
default :
PORTB = 0X00;
break;
}
if(segno==1) {
PORTA = Seg4;
}
if(segno==2) {
PORTA = Seg3;
}
if(segno==3) {
PORTA = Seg2;
}
if(segno==4) {
PORTA = Seg1;
}
if(segno==5) {
PORTC=0X00;
PORTC = 0x40;//DP2 fourth Segment
// PORTCbits.RC5=1;
}
if(segno==6) {
PORTC=0X00;
PORTC= 0x20;//DP2 third Segment
//PORTCbits.RC6=1;
}
if(segno==7) {
PORTA=0X00;
PORTA = Seg5; //DP2 Second Segment
// PORTAbits.RA4=1;
}
if(segno==8) {
PORTA=0X00;
PORTA = Seg6; //DP2 First Segment
// PORTAbits.RA5=1;
}
}
unsigned int bcdtodecimal(unsigned int bcd) {
unsigned int decimal;
decimal = (((bcd & 0xF0) >> 4) * 10) + (bcd & 0x0F);
return decimal;
}
void ISR_Routine(void) {
if(PIR0bits.TMR0IF==1) {
PIR0bits.TMR0IF = 0;
count= count+1;
if(count>=10) {
Flag_Update=1;
count=0;
LED=!LED;
}
}
}
void main(void) {
// Initialize the device
SYSTEM_Initialize();
INTCONbits.GIE=1;
INTCONbits.PEIE=1;
I2C1_Initialize();
I2C1_Write1ByteRegister(0x6F,0x00,0x10);//sec
I2C1_Write1ByteRegister(0x6F,0x01,0x20);//min
I2C1_Write1ByteRegister(0x6F,0x02,0x01);//Hour
I2C1_Write1ByteRegister(0x6F,0x03,0x01);
I2C1_Write1ByteRegister(0x6F,0x04,0x02);
I2C1_Write1ByteRegister(0x6F,0x05,0x03);
I2C1_Write1ByteRegister(0x6F,0x06,0x10);
I2C1_Write1ByteRegister(0x6F,0x07,0x48);
while (1)
{
sec=I2C1_Read1ByteRegister(0x6F,0x00);
min=I2C1_Read1ByteRegister(0x6F,0x01);
if(Flag_Update==1) {
SetSeg(min >> 4,4);
__delay_ms(5);
SetSeg(min & 0x0f,3);
__delay_ms(5);
SetSeg(sec >> 4,2);
__delay_ms(5);
SetSeg(sec & 0x0f,1);
__delay_ms(5);
Flag_Update = 0; //ready for next update
}
}
}
解决方案
在两者之间添加一些延迟,
I2C1_Initialize();
比如说I2C1_Write1ByteRegister(0x6F,0x00,0x10);
10 毫秒。有时 I2C 模块在初始化后需要一些延迟。它大约是几微秒,但我个人推荐 1ms 或 10ms。将 read 函数都放在
sec=I2C1_Read1ByteRegister(0x6F,0x00);
里面min=I2C1_Read1ByteRegister(0x6F,0x01);
,if(Flag_Update==1)
因为MCP7940N
只有当你要在七段屏幕上显示时你才应该阅读。在调试模式 (
with variable watch
) 中检查您的变量min
和sec
实际更新与否..?如果两者都以实际实时正确更新,则检查您的SetSeg
功能。
推荐阅读
- office-js - 是否可以从 Office JS API 调用 Words 函数“比较...”?
- c# - 如何统一更改按钮颜色?
- isabelle - 这个伊莎贝尔证明有什么问题?
- c - 列出双向链表项 C
- javascript - 当达到父组件的宽度时输入文本移动到下一行
- c# - 具有变量值的字典对象的通用方法并循环遍历它
- c++ - 蛇游戏——尾巴运动
- css - 使用 CSS Grid 的文章布局:如何在图像周围环绕文本(或浮动它们)?
- javascript - 我的 Wordpress 网站页面滚动不起作用
- android - 使用 React-Native-Bluetooth-Classic 构建失败