各位坛友老师好,以下是STC8G1K08+RX8025T+OLED万年历程序,编译不通过,我是新手。那位老师帮忙指点一下,在这里表示感谢!
编译错误截图
- #include <STC8G.H>
- #include <intrins.h>
- // 定义I2C引脚
- sbit SDA = P3^2;
- sbit SCL = P3^1;
- // 定义按键引脚
- sbit KEY_SET = P3^3;
- sbit KEY_UP = P3^4;
- sbit KEY_DN = P3^5;
- // OLED参数
- #define OLED_ADDR 0x3C // OLED I2C地址
- #define RX8025T_ADDR 0x32 // RX8025T I2C地址
- // 星期定义
- char *weekdays[] = {"日", "一", "二", "三", "四", "五", "六"};
- // 时间结构体
- struct DateTime {
- unsigned char second;
- unsigned char minute;
- unsigned char hour;
- unsigned char day; // 星期
- unsigned char date; // 日
- unsigned char month;
- unsigned char year;
- };
- // 全局变量
- struct DateTime currentTime;
- bit setMode = 0; // 0:正常模式, 1:设置模式
- unsigned char setPos = 0; // 设置位置:0=年,1=月,2=日,3=时,4=分,5=秒
- unsigned char blinkCnt = 0; // 闪烁计数器
- // 函数声明
- void I2C_Start();
- void I2C_Stop();
- bit I2C_Write(unsigned char dat);
- unsigned char I2C_Read(bit ack);
- void OLED_WriteCmd(unsigned char cmd);
- void OLED_WriteData(unsigned char dat);
- void OLED_Init();
- void OLED_SetPos(unsigned char x, unsigned char y);
- void OLED_ShowChar(unsigned char x, unsigned char y, char c);
- void OLED_ShowStr(unsigned char x, unsigned char y, char *str);
- void RX8025T_ReadTime();
- void RX8025T_WriteTime();
- void Key_Scan();
- void Display_Time();
- void Display_Date();
- void Display_Temperature();
- void NumToStr(unsigned char num, char *str);
- void DelayMS(unsigned int ms);
- // I2C起始信号
- void I2C_Start() {
- SDA = 1;
- SCL = 1;
- _nop_(); _nop_();
- SDA = 0;
- _nop_(); _nop_();
- SCL = 0;
- }
- // I2C停止信号
- void I2C_Stop() {
- SDA = 0;
- SCL = 1;
- _nop_(); _nop_();
- SDA = 1;
- _nop_(); _nop_();
- }
- // I2C写一个字节
- bit I2C_Write(unsigned char dat) {
- unsigned char i;
- bit ack;
- for(i=0; i<8; i++) {
- SDA = (dat & 0x80) ? 1 : 0;
- dat <<= 1;
- SCL = 1;
- _nop_(); _nop_(); _nop_();
- SCL = 0;
- }
- SDA = 1; // 释放SDA
- SCL = 1;
- _nop_(); _nop_();
- ack = SDA; // 读取ACK
- SCL = 0;
- return ack;
- }
- // I2C读一个字节
- unsigned char I2C_Read(bit ack) {
- unsigned char i, dat = 0;
- SDA = 1; // 释放SDA
- for(i=0; i<8; i++) {
- SCL = 1;
- _nop_(); _nop_();
- dat <<= 1;
- if(SDA) dat |= 0x01;
- SCL = 0;
- _nop_(); _nop_();
- }
- // 发送ACK/NACK
- SDA = ack;
- SCL = 1;
- _nop_(); _nop_(); _nop_();
- SCL = 0;
- SDA = 1; // 释放SDA
- return dat;
- }
- // OLED写命令
- void OLED_WriteCmd(unsigned char cmd) {
- I2C_Start();
- I2C_Write(OLED_ADDR << 1);
- I2C_Write(0x00); // 命令标识
- I2C_Write(cmd);
- I2C_Stop();
- }
- // OLED写数据
- void OLED_WriteData(unsigned char dat) {
- I2C_Start();
- I2C_Write(OLED_ADDR << 1);
- I2C_Write(0x40); // 数据标识
- I2C_Write(dat);
- I2C_Stop();
- }
- // OLED初始化
- void OLED_Init() {
- DelayMS(100);
- OLED_WriteCmd(0xAE); // 关闭显示
-
- OLED_WriteCmd(0xD5); // 设置显示时钟分频
- OLED_WriteCmd(0x80);
-
- OLED_WriteCmd(0xA8); // 设置复用率
- OLED_WriteCmd(0x3F);
-
- OLED_WriteCmd(0xD3); // 设置显示偏移
- OLED_WriteCmd(0x00);
-
- OLED_WriteCmd(0x40); // 设置起始行
-
- OLED_WriteCmd(0x8D); // 电荷泵设置
- OLED_WriteCmd(0x14); // 开启电荷泵
-
- OLED_WriteCmd(0x20); // 内存模式
- OLED_WriteCmd(0x00); // 水平寻址模式
-
- OLED_WriteCmd(0xA1); // 段重映射
- OLED_WriteCmd(0xC8); // 行重映射
-
- OLED_WriteCmd(0xDA); // 设置COM硬件
- OLED_WriteCmd(0x12);
-
- OLED_WriteCmd(0x81); // 对比度设置
- OLED_WriteCmd(0xCF);
-
- OLED_WriteCmd(0xD9); // 预充电周期
- OLED_WriteCmd(0xF1);
-
- OLED_WriteCmd(0xDB); // VCOMH设置
- OLED_WriteCmd(0x40);
-
- OLED_WriteCmd(0xA4); // 正常显示
- OLED_WriteCmd(0xA6); // 非反转显示
-
- OLED_WriteCmd(0xAF); // 开启显示
- }
- // 设置显示位置
- void OLED_SetPos(unsigned char x, unsigned char y) {
- OLED_WriteCmd(0xB0 + y); // 设置页地址
- OLED_WriteCmd(((x & 0xF0) >> 4) | 0x10); // 设置列地址高4位
- OLED_WriteCmd(x & 0x0F); // 设置列地址低4位
- }
- // 5x7字体字模
- const unsigned char Font5x7[][5] = {
- {0x3E,0x45,0x49,0x51,0x3E}, // 0
- {0x00,0x21,0x7F,0x01,0x00}, // 1
- {0x23,0x45,0x49,0x49,0x31}, // 2
- {0x22,0x49,0x49,0x49,0x36}, // 3
- {0x0C,0x14,0x24,0x7F,0x04}, // 4
- {0x72,0x51,0x51,0x51,0x4E}, // 5
- {0x1E,0x29,0x49,0x49,0x06}, // 6
- {0x40,0x47,0x48,0x50,0x60}, // 7
- {0x36,0x49,0x49,0x49,0x36}, // 8
- {0x30,0x49,0x49,0x4A,0x3C}, // 9
- {0x00,0x36,0x36,0x00,0x00}, // :
- {0x00,0x00,0x7F,0x00,0x00}, // -
- {0x7F,0x48,0x48,0x48,0x30}, // T
- {0x41,0x22,0x1C,0x22,0x41} // W
- };
- // 显示单个字符
- void OLED_ShowChar(unsigned char x, unsigned char y, char c,unsigned char i) {
- unsigned char idx = 0;
-
- if(c >= '0' && c <= '9') {
- idx = c - '0';
- }
- else if(c == ':') {
- idx = 10;
- }
- else if(c == '-') {
- idx = 11;
- }
- else if(c == 'T') {
- idx = 12;
- }
- else if(c == 'W') {
- idx = 13;
- }
- else {
- return; // 不支持的字符
- }
-
- OLED_SetPos(x, y);
- // for(unsigned char i=0; i<5; i++) {
- for(i=0; i<5; i++) {
- OLED_WriteData(Font5x7[idx][i]);
- }
- OLED_WriteData(0x00); // 字符间距
- }
- // 显示字符串
- void OLED_ShowStr(unsigned char x, unsigned char y, char *str) {
- while(*str) {
- OLED_ShowChar(x, y, *str++);
- x += 6; // 每个字符占6列(5像素+1间距)
- }
- }
- // 数字转字符串
- void NumToStr(unsigned char num, char *str) {
- str[0] = num / 10 + '0';
- str[1] = num % 10 + '0';
- str[2] = '\0';
- }
- // 从RX8025T读取时间
- void RX8025T_ReadTime() {
- I2C_Start();
- I2C_Write(RX8025T_ADDR << 1); // 写地址
- I2C_Write(0x00); // 起始地址(秒寄存器)
-
- I2C_Start();
- I2C_Write((RX8025T_ADDR << 1) | 0x01); // 读地址
-
- currentTime.second = I2C_Read(1); // 发送ACK继续读
- currentTime.minute = I2C_Read(1);
- currentTime.hour = I2C_Read(1);
- currentTime.day = I2C_Read(1);
- currentTime.date = I2C_Read(1);
- currentTime.month = I2C_Read(1);
- currentTime.year = I2C_Read(0); // 最后字节发送NACK
- I2C_Stop();
-
- // 转换BCD码
- currentTime.second = (currentTime.second >> 4) * 10 + (currentTime.second & 0x0F);
- currentTime.minute = (currentTime.minute >> 4) * 10 + (currentTime.minute & 0x0F);
- currentTime.hour = (currentTime.hour >> 4) * 10 + (currentTime.hour & 0x0F);
- currentTime.date = (currentTime.date >> 4) * 10 + (currentTime.date & 0x0F);
- currentTime.month = (currentTime.month >> 4) * 10 + (currentTime.month & 0x0F);
- currentTime.year = (currentTime.year >> 4) * 10 + (currentTime.year & 0x0F);
- }
- // 向RX8025T写入时间
- void RX8025T_WriteTime() {
- I2C_Start();
- I2C_Write(RX8025T_ADDR << 1); // 写地址
- I2C_Write(0x00); // 起始地址(秒寄存器)
-
- // 转换BCD码
- I2C_Write(((currentTime.second / 10) << 4) | (currentTime.second % 10));
- I2C_Write(((currentTime.minute / 10) << 4) | (currentTime.minute % 10));
- I2C_Write(((currentTime.hour / 10) << 4) | (currentTime.hour % 10));
- I2C_Write(currentTime.day);
- I2C_Write(((currentTime.date / 10) << 4) | (currentTime.date % 10));
- I2C_Write(((currentTime.month / 10) << 4) | (currentTime.month % 10));
- I2C_Write(((currentTime.year / 10) << 4) | (currentTime.year % 10));
-
- I2C_Stop();
- }
- // 按键扫描
- void Key_Scan() {
- static unsigned char keyCount = 0;
- static bit keyFlag = 0;
-
- if(!KEY_SET || !KEY_UP || !KEY_DN) {
- keyCount++;
- if(keyCount >= 20) { // 消抖
- keyCount = 0;
- if(!keyFlag) {
- keyFlag = 1;
-
- if(!KEY_SET) {
- if(!setMode) {
- setMode = 1;
- setPos = 0; // 进入设置模式
- }
- else {
- setPos++; // 切换到下一个设置项
- if(setPos > 5) { // 设置完成
- setMode = 0;
- RX8025T_WriteTime(); // 保存时间
- }
- }
- }
-
- if(setMode) {
- if(!KEY_UP) {
- switch(setPos) {
- case 0: currentTime.year = (currentTime.year < 99) ? currentTime.year+1 : 0; break;
- case 1: currentTime.month = (currentTime.month < 12) ? currentTime.month+1 : 1; break;
- case 2: currentTime.date = (currentTime.date < 31) ? currentTime.date+1 : 1; break;
- case 3: currentTime.hour = (currentTime.hour < 23) ? currentTime.hour+1 : 0; break;
- case 4: currentTime.minute = (currentTime.minute < 59) ? currentTime.minute+1 : 0; break;
- case 5: currentTime.second = (currentTime.second < 59) ? currentTime.second+1 : 0; break;
- }
- }
-
- if(!KEY_DN) {
- switch(setPos) {
- case 0: currentTime.year = (currentTime.year > 0) ? currentTime.year-1 : 99; break;
- case 1: currentTime.month = (currentTime.month > 1) ? currentTime.month-1 : 12; break;
- case 2: currentTime.date = (currentTime.date > 1) ? currentTime.date-1 : 31; break;
- case 3: currentTime.hour = (currentTime.hour > 0) ? currentTime.hour-1 : 23; break;
- case 4: currentTime.minute = (currentTime.minute > 0) ? currentTime.minute-1 : 59; break;
- case 5: currentTime.second = (currentTime.second > 0) ? currentTime.second-1 : 59; break;
- }
- }
- }
- }
- }
- }
- else {
- keyCount = 0;
- keyFlag = 0;
- }
- }
- // 显示日期
- void Display_Date() {
- char str[3];
-
- // 显示年月日
- OLED_ShowStr(0, 0, "20");
- NumToStr(currentTime.year, str);
- OLED_ShowStr(12, 0, str);
- OLED_ShowChar(24, 0, '-');
-
- NumToStr(currentTime.month, str);
- OLED_ShowStr(30, 0, str);
- OLED_ShowChar(42, 0, '-');
-
- NumToStr(currentTime.date, str);
- OLED_ShowStr(48, 0, str);
-
- // 显示星期
- OLED_ShowStr(72, 0, "W");
- str[0] = '0' + (currentTime.day % 7); // 显示0-6
- str[1] = '\0';
- OLED_ShowStr(78, 0, str);
- }
- // 显示时间
- void Display_Time() {
- char str[3];
-
- NumToStr(currentTime.hour, str);
- OLED_ShowStr(0, 2, str);
- OLED_ShowChar(12, 2, ':');
-
- NumToStr(currentTime.minute, str);
- OLED_ShowStr(18, 2, str);
- OLED_ShowChar(30, 2, ':');
-
- NumToStr(currentTime.second, str);
- OLED_ShowStr(36, 2, str);
- }
- }
- // 主函数
- void main() {
- // 初始化IO口
- P3M0 = 0x00;
- P3M1 = 0x00; // 准双向模式
-
- // 初始化OLED
- OLED_Init();
-
- // 初始化时间 (示例时间)
- currentTime.year = 23;
- currentTime.month = 1;
- currentTime.date = 1;
- currentTime.day = 0; // 星期日
- currentTime.hour = 12;
- currentTime.minute = 0;
- currentTime.second = 0;
- RX8025T_WriteTime(); // 写入初始时间
-
- while(1) {
- RX8025T_ReadTime(); // 读取时间
- Key_Scan(); // 按键扫描
-
- // 清屏
- OLED_WriteCmd(0x20); // 水平寻址模式
- OLED_WriteCmd(0x00); // 列起始地址0
- OLED_WriteCmd(0x10); // 列结束地址127
- OLED_WriteCmd(0x00); // 页起始地址0
- OLED_WriteCmd(0x07); // 页结束地址7
-
- // 显示信息
- Display_Date();
- Display_Time();
- Display_Temperature();
-
- // 设置模式闪烁指示
- if(setMode) {
- blinkCnt++;
- if(blinkCnt > 100) {
- switch(setPos) {
- case 0: OLED_ShowStr(12, 0, " "); break; // 年
- case 1: OLED_ShowStr(30, 0, " "); break; // 月
- case 2: OLED_ShowStr(48, 0, " "); break; // 日
- case 3: OLED_ShowStr(0, 2, " "); break; // 时
- case 4: OLED_ShowStr(18, 2, " "); break; // 分
- case 5: OLED_ShowStr(36, 2, " "); break; // 秒
- }
- if(blinkCnt > 200) blinkCnt = 0;
- }
- }
-
- DelayMS(10);
- }
- }
- // 简单延时函数
- void DelayMS(unsigned int ms) {
- unsigned int i, j;
- for(i=0; i<ms; i++)
- for(j=0; j<1000; j++);
- }
复制代码
|