本帖最后由 whoyzf 于 2024-11-5 18:10 编辑
-
-
- /*********************************************************/
- #define MAIN_Fosc 11059200L //定义主时钟
-
- #include "STC8H4K64TL.h"
-
-
- /************* 功能说明 **************
- 888e
- 硬件连接及LCD_buff
- SEG22 SEG21 SEG20 SEG19 SEG18 SEG17
- 1 2 3 4 10 9 8 7 6 5
- COM0 3A 4A 2A 4D 1A 4G C0SEGV2
- COM1 3B 3F 2B 2F 1B 1F C1SEGV2
- COM2 3C 3G 2C 2G 1C 1G C2SEGV2
- COM3 3D 3E 2D 2E 1D 1E C1SEGV2
-
-
-
- ******************************************/
-
- /************* 本地常量声明 **************/
-
-
- /************* 本地IO定义 **************/
-
-
- /************* 本地变量声明 **************/
-
- bit B_500mS; // 0.5秒时隙标志
- bit B_20ms; // 20ms时隙标志
- u8 OpTime; // 此变量非0时, 不睡眠, 连续运行程序(本例串口唤醒后连续运行5秒, 以便正确接收串口数据)
-
-
- u8 uc0_5sflag=0;
-
- /************* 本地函数声明 **************/
-
- u8 Timer0_Config(u32 reload); //reload值是主时钟周期数
- void LCD_config(void);
-
- void ReadKey(void); //50ms call
-
- unsigned char segmentCodes[10] = {
- 0x3F, // 0 - a-g: 00011111
- 0x06, // 1 - a-g: 00000110
- 0x5B, // 2 - a-g: 01011011
- 0x4F, // 3 - a-g: 01001111
- 0x66, // 4 - a-g: 01100110
- 0x6D, // 5 - a-g: 01101101
- 0x7d, // 6 - a-g: 01111101
- 0x07, // 7 - a-g: 00000111
- 0x7F, // 8 - a-g: 01111111
- 0x6f // 9 - a-g: 01101111
- };
-
- /****************** 对第1~5数字装载显示函数 ***************************/
- u8 code t_display[]={ //标准字库
- // 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
- //black - H J K L N o P U t G Q r M y
- 0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e};
-
-
-
- void displayThreeDigits(unsigned int number) ;
- void updateSegments(unsigned char hundreds,unsigned char tens,unsigned char units);
-
- // 函数用于显示一个三位数
- void displayThreeDigits(unsigned int number) {
- unsigned char hundreds ; // 百位
- unsigned char tens ; // 十位
- unsigned char units ; // 个位
-
-
- hundreds = number / 100; // 百位
- tens = (number / 10) % 10; // 十位
- units = number % 10; // 个位
-
- // 初始化寄存器
- C0SEGV2 = 0x00;
- C1SEGV2 = 0x00;
- C2SEGV2 = 0x00;
- C3SEGV2 = 0x00;
-
- updateSegments(hundreds,tens,units);
- }
-
- // 函数用于更新段寄存器
- void updateSegments(unsigned char hundreds,unsigned char tens,unsigned char units) {
-
- // 左起第一位,控制1A到1G位
- if ((segmentCodes[hundreds] & 0x01) == 0) C0SEGV2 &= 0xfb; else C0SEGV2 |= 0x04; // 1A位是0,或者1
- if ((segmentCodes[hundreds] & 0x02) == 0) C1SEGV2 &= 0xfb; else C1SEGV2 |= 0x04; // 1B位是0,或者1
- if ((segmentCodes[hundreds] & 0x04) == 0) C2SEGV2 &= 0xfb; else C2SEGV2 |= 0x04; // 1C位是0,或者1
- if ((segmentCodes[hundreds] & 0x08) == 0) C3SEGV2 &= 0xfb; else C3SEGV2 |= 0x04; // 1D位是0,或者1
- if ((segmentCodes[hundreds] & 0x10) == 0) C3SEGV2 &= 0xfd; else C3SEGV2 |= 0x02; // 1E位是0,或者1
- if ((segmentCodes[hundreds] & 0x20) == 0) C1SEGV2 &= 0xfd; else C1SEGV2 |= 0x02; // 1F位是0,或者1
- if ((segmentCodes[hundreds] & 0x40) == 0) C2SEGV2 &= 0xfd; else C2SEGV2 |= 0x02; // 1G位是0,或者1
-
- // 左起第二位,控制2A到2G位
- if ((segmentCodes[tens] & 0x01) == 0) C0SEGV2 &= 0xef; else C0SEGV2 |= 0x10;
- if ((segmentCodes[tens] & 0x02) == 0) C1SEGV2 &= 0xef; else C1SEGV2 |= 0x10;
- if ((segmentCodes[tens] & 0x04) == 0) C2SEGV2 &= 0xef; else C2SEGV2 |= 0x10;
- if ((segmentCodes[tens] & 0x08) == 0) C3SEGV2 &= 0xef; else C3SEGV2 |= 0x10;
- if ((segmentCodes[tens] & 0x10) == 0) C3SEGV2 &= 0xf7; else C3SEGV2 |= 0x08;
- if ((segmentCodes[tens] & 0x20) == 0) C1SEGV2 &= 0xf7; else C1SEGV2 |= 0x08;
- if ((segmentCodes[tens] & 0x40) == 0) C2SEGV2 &= 0xf7; else C2SEGV2 |= 0x08;
-
- // 左起第三位,控制3A到3G位
- if ((segmentCodes[units] & 0x01) == 0) C0SEGV2 &= 0xbf; else C0SEGV2 |= 0x40;
- if ((segmentCodes[units] & 0x02) == 0) C1SEGV2 &= 0xbf; else C1SEGV2 |= 0x40;
- if ((segmentCodes[units] & 0x04) == 0) C2SEGV2 &= 0xbf; else C2SEGV2 |= 0x40;
- if ((segmentCodes[units] & 0x08) == 0) C3SEGV2 &= 0xbf; else C3SEGV2 |= 0x40;
- if ((segmentCodes[units] & 0x10) == 0) C3SEGV2 &= 0xdf; else C3SEGV2 |= 0x20;
- if ((segmentCodes[units] & 0x20) == 0) C1SEGV2 &= 0xdf; else C1SEGV2 |= 0x20;
- if ((segmentCodes[units] & 0x40) == 0) C2SEGV2 &= 0xdf; else C2SEGV2 |= 0x20;
-
- }
-
-
-
- void main(void)
- {
- unsigned char ucshow=0,i=0;
- P0M1 = 0; P0M0 = 0;
- P1M1 = 0; P1M0 = 0;
- P2M1 = 0; P2M0 = 0;
- P3M1 = 0X80; P3M0 = 0;
- P4M1 = 0; P4M0 = 0;
- P5M1 = 0; P5M0 = 0;
- P6M1 = 0; P6M0 = 0;
- P7M1 = 0; P7M0 = 0;
-
- Timer0_Config(MAIN_Fosc / 50); //reload值是主时钟周期数, (中断频率, 50次/秒)
-
- EA = 1;
- P37=0;
-
- // OpTime = 0;
- // DisMode = 0;
- // RTC_config();
- LCD_config();
- while(1)
- {
- if(uc0_5sflag==1)
- {
- uc0_5sflag=0;
-
- ucshow++;
-
- // COMLENM=ucshow;
- // COMLENL=(255-ucshow);
- // C0SEGV2=ucshow;
- // C1SEGV2=ucshow;
- // C3SEGV2=ucshow;
- C0SEGV2 = 0x00;
- C1SEGV2 = 0x00;
- C2SEGV2 = 0x00;
- C3SEGV2 = 0x00;
-
- // 设置C0SEGV2, C1SEGV2, C2SEGV2, C3SEGV2寄存器
- // C0SEGV2 = segValues[1][0];
- // C1SEGV2 = segValues[1][1];
- // C2SEGV2 = segValues[1][2];
- // C3SEGV2 = segValues[1][3];
- //i=8;
- /*
- //左起第一位,
- if ((segmentCodes[i] & 0x01) == 0) C0SEGV2 &= 0xfb; // 1A位是0
- else C0SEGV2 |= 0x04; // 1A位是1
- if ((segmentCodes[i] & 0x02) == 0) C1SEGV2 &= 0xfb; // 1B位是0
- else C1SEGV2 |= 0x04; // 1B位是1
- if ((segmentCodes[i] & 0x04) == 0) C2SEGV2 &= 0xfb; // 1C位是0
- else C2SEGV2 |= 0x04; // 1C位是1
- if ((segmentCodes[i] & 0x08) == 0) C3SEGV2 &= 0xfb; // 1D位是0
- else C3SEGV2 |= 0x04; // 1D位是1
-
- if ((segmentCodes[i] & 0x10) == 0) C3SEGV2 &= 0xfd; // 1E位是0
- else C3SEGV2 |= 0x02; // 1E位是1
- if ((segmentCodes[i] & 0x20) == 0) C1SEGV2 &= 0xfd; // 1F位是0
- else C1SEGV2 |= 0x02; // 1F位是1
- if ((segmentCodes[i] & 0x40) == 0) C2SEGV2 &= 0xfd; // 1G位是0
- else C2SEGV2 |= 0x02; // 1G位是1
- //if ((segmentCodes[i] & 0x08) == 0) // 1H位是0
- // else // 1H位是1
-
- //左起第二位,
- if ((segmentCodes[i] & 0x01) == 0) C0SEGV2 &= 0xef; // 2A位是0
- else C0SEGV2 |= 0x10; // 2A位是1
- if ((segmentCodes[i] & 0x02) == 0) C1SEGV2 &= 0xef; // 2B位是0
- else C1SEGV2 |= 0x10; // 2B位是1
- if ((segmentCodes[i] & 0x04) == 0) C2SEGV2 &= 0xef; // 2C位是0
- else C2SEGV2 |= 0x10; // 2C位是1
- if ((segmentCodes[i] & 0x08) == 0) C3SEGV2 &= 0xef; // 2D位是0
- else C3SEGV2 |= 0x10; // 2D位是1
-
- if ((segmentCodes[i] & 0x10) == 0) C3SEGV2 &= 0xf7; // 2E位是0
- else C3SEGV2 |= 0x08; // 2E位是1
- if ((segmentCodes[i] & 0x20) == 0) C1SEGV2 &= 0xf7; // 2F位是0
- else C1SEGV2 |= 0x08; // 2F位是1
- if ((segmentCodes[i] & 0x40) == 0) C2SEGV2 &= 0xf7; // 2G位是0
- else C2SEGV2 |= 0x08; // 2G位是1
- //if ((segmentCodes[i] & 0x08) == 0) // 1H位是0
- // else
-
- //左起第二位,
- if ((segmentCodes[i] & 0x01) == 0) C0SEGV2 &= 0xbf; // 3A位是0
- else C0SEGV2 |= 0x40; // 3A位是1
- if ((segmentCodes[i] & 0x02) == 0) C1SEGV2 &= 0xbf; // 3B位是0
- else C1SEGV2 |= 0x40; // 3B位是1
- if ((segmentCodes[i] & 0x04) == 0) C2SEGV2 &= 0xbf; // 3C位是0
- else C2SEGV2 |= 0x40; // 3C位是1
- if ((segmentCodes[i] & 0x08) == 0) C3SEGV2 &= 0xbf; // 3D位是0
- else C3SEGV2 |= 0x40; // 3D位是1
-
- if ((segmentCodes[i] & 0x10) == 0) C3SEGV2 &= 0xdf; // 3E位是0
- else C3SEGV2 |= 0x20; // 3E位是1
- if ((segmentCodes[i] & 0x20) == 0) C1SEGV2 &= 0xdf; // 3F位是0
- else C1SEGV2 |= 0x20; // 3F位是1
- if ((segmentCodes[i] & 0x40) == 0) C2SEGV2 &= 0xdf; // 3G位是0
- else C2SEGV2 |= 0x20; // 3G位是1
- //if ((segmentCodes[i] & 0x08) == 0) // 1H位是0
- // else
-
- */
- displayThreeDigits(i);
-
-
-
-
- i++;
- if(i>250)i=0;
-
-
-
-
- if(ucshow>=0xFF)
- {
- ucshow=0x00;
- // X32KCR = 0x00;
- }
- }
-
-
-
- }
-
-
- }
-
-
- /********************* INT0中断函数 *************************/
- void Ext_INT0 (void) interrupt 0
- {
- OpTime = 6;
- }
-
-
-
- /********************** LCD配置函数 *****************************/
- void LCD_config(void)
- {
- // u8 i;
-
- P_SW2 |= 0x80; // SFR enable
-
- // X32KCR = 0x80 + 0x40; //启动外部32K晶振, 低增益+0x00, 高增益+0x40.
- // P1n_pure_input(0xc0); //P1.6 P1.7设置为高阻输入
- // P1IE = ~0xc0; //P1.6 P1.7关闭数字输入功能
- // X32KCR = 0x80;
-
- LCDCFG = 0xc0 + 7; // 0x00:选择CPU时钟为LCD时钟, 0x80: 选择外部32K晶振做时钟. VLCD电压选择0~7对应0.65+VLCD*0.05.
- // LCDCFG|=0x07;
-
- // X32KCR = 0x80 + 0x40; //启动外部32K晶振, 低增益+0x00, 高增益+0x40.
- P1n_pure_input(0xc0); //P1.6 P1.7设置为高阻输入
- P1IE = ~0xc0; //P1.6 P1.7关闭数字输入功能
- X32KCR = 0x80;
-
-
-
- DBLEN = 0; // 设置LCD显示时的死区时间长度, 取值0~7.
- COMLENH = 0; // COM时间长度设置 高字节COMLEN[19:16], 一共20bit.
- COMLENM = 0; // COM时间长度设置 中字节COMLEN[15:8] LCD刷新率 = LCD时钟频率 / ((DBLEN[2:0]+COMLEN[19:0]+1) *2 * COM数)
- COMLENL = 65; // COM时间长度设置 低字节COMLEN[7:0] LCD刷新率 = 32768/((2+65+1)*2*4) = 60Hz
- BLINKRATE = 60; // 闪烁率配置寄存器, LCD闪烁率 = LCD刷新率 / BLINKRATE[7:0] Hz
-
- COMON = 0x0f; // COM使能寄存器
- SEGON1 = 0x00; // SEG线使能寄存器1, SEG7~SEG0
- SEGON2 = 0x00; // SEG线使能寄存器2, SEG15~SEG8
- SEGON3 = 0x7e; // SEG线使能寄存器3, SEG23~SEG16
- SEGON4 = 0x00; // SEG线使能寄存器4, SEG31~SEG24
- SEGON5 = 0x00; // SEG线使能寄存器5, SEG39~SEG32
-
- // P5n_pure_input(0x03); //P5.0 P5.1 设置为高阻输入 COM0 COM1
- // P3n_pure_input(0x60); //P3.5 P3.6 设置为高阻输入 COM2 COM3
- // P3M0 = 0x00; P3M1 = 0xFF;
- // P5M0 = 0x00; P5M1 = 0xFF;
-
- // P3DR = 0x00;
- // P0DR = 0x00;
-
-
- // LCDCFG2 = 0x0f; // SEG0~3切换到P7.7~7.4
- // P7n_pure_input(0xf0); //P7.7~P7.4 设置为高阻输入 SEG0~SEG3 (对应P7.7~7.4)
- // P4n_pure_input(0x80); //P4.7 设置为高阻输入 SEG4
- // P1n_pure_input(0x03); //P1.1~P1.0 设置为高阻输入 SEG5 SEG6 (对应P1.1 P1.0)
- // P0n_pure_input(0x60); //P0.7~P0.5 设置为高阻输入 SEG7 SEG8 SEG9 (对应P0.7 P0.6 P0.5)
- // P5n_pure_input(0x0C); //P5.3 P5.2 设置为高阻输入 SEG10 SEG11 (对应P5.3 P5.2)
- // P0n_pure_input(0x1f); //P0.4~P0.0 设置为高阻输入 SEG12~SEG16 (对应P0.4 ~ 0.0)
- // P4n_pure_input(0x60); //P4.6 P4.5 设置为高阻输入 SEG17 SEG18
- // P2n_pure_input(0xF0); //P2.7~P2.0 设置为高阻输入 SEG19~SEG26 (对应P2.7~2.0)
- // P2M0 = 0x00; P2M1 = 0xFF;
- // P4M0 = 0x00; P4M1 = 0xFF;
- // P2DR = 0x00;
- // P4DR = 0x00;
- // P4n_pure_input(0x1e); //P4.4~P4.1 设置为高阻输入 SEG27~SEG30 (对应P4.4~4.1)
- // P3n_pure_input(0x80); //P3.7 设置为高阻输入 SEG31
- // P7n_pure_input(0x0f); //P7.3~P7.0 设置为高阻输入 SEG32~SEG35 (对应P7.3~7.0)
- // P6n_pure_input(0x0f); //P6.0~P6.3 设置为高阻输入 SEG36~SEG39 (对应P6.3~6.0)
-
-
- C0SEGV2 = 0x00;
- C1SEGV2 = 0x00;
- C2SEGV2 = 0x00;
- C3SEGV2 = 0x00;
-
-
- LCDCR = (0<<1) + 1; // LCD控制寄存器, 0:普通模式, 1:长暗模式, 2:长亮模式, 3:闪烁模式. +0:禁止LCD模块, +1:允许LCD模块.
-
- }
-
-
-
- //========================================================================
- // 函数:u8 Timer0_Config(u32 reload)
- // 描述: timer0初始化函数.
- // 参数: reload: 重装值.
- // 返回: 0: 初始化正确, 1: 重装值过大, 初始化错误.
- // 版本: V1.0, 2018-3-5
- //========================================================================
- u8 Timer0_Config(u32 reload) //t=0: reload值是主时钟周期数, t=1: reload值是时间(单位us)
- {
- TR0 = 0; //停止计数
-
- if(reload >= (65536UL * 12)) return 1; //值过大, 返回错误
- if(reload < 65536UL) AUXR |= 0x80; //1T mode
- else
- {
- AUXR &= ~0x80; //12T mode
- reload = reload / 12;
- }
- reload = 65536UL - reload;
- TH0 = (u8)(reload >> 8);
- TL0 = (u8)(reload);
-
- ET0 = 1; //允许中断
- TMOD = (TMOD & ~0x03) | 0; //工作模式, 0: 16位自动重装, 1: 16位定时/计数, 2: 8位自动重装, 3: 16位自动重装, 不可屏蔽中断
- TR0 = 1; //开始运行
- return 0;
- }
-
- //========================================================================
- // 函数: void timer0_int (void) interrupt TIMER0_VECTOR
- // 描述: timer0中断函数.
- // 参数: none.
- // 返回: none.
- // 版本: V1.0, 2016-5-12
- //========================================================================
- void timer0_ISR (void) interrupt TIMER0_VECTOR
- {
- static u8 i;
-
- B_20ms = 1; //20ms时隙标志
-
- i++;
- if(i>=5)
- {
- i=0;
- uc0_5sflag=1;
- // P37=!P37;
- }
-
- }
-
-
-
-
复制代码
|