188数码管驱动程序(简洁)
此程序已不是产品最新程序该版本有以下缺点:1、占用RAM和ROM多新版本只需要一个u8 Segment[11]数组而且存在ROM中大大减少占用RAM和ROM。2、低透光率外壳下存在笔画不均的问题外壳越暗越明显。原因是共阴的多段数码管同时点亮时留过限流电阻的电流大限流电阻压降变大数码管分得电压偏小导致某几段亮度偏暗新版程序已经解决此问题。3、有同学反馈残影问题应该不是此程序的bug因为我自己使用是没问题的不少同学移植后也没问题建议残影同学检查是不是受到其他程序干扰最好新建工程单独验证此程序没问题后再移植。最新版本在以下连接也是量产版本188数码管新版本简单易懂-CSDN博客顺便说下诡异的残影问题有些同学移植后完全正常有些同学移植后出现残影这个跟MCU的IO口速度有关系arm单片机建议设置最大频率然后再加快扫描速度就可以解决残影问题亲测有效。评论区有位大神的代码说比我的简短高效很多大家可以参考对比一下然后说说意见。以下是厂家提供的188数码管的电路原理图在Excel上画出管脚与段码之间的关系横向高电平竖向低电平例如B3表示DIG3个位的B段点亮的条件是P2为高电平,P1为低电平。数码管显示思路188总共有16个段码用u16 类型变量(display_sram)的16个bit表示16个段码的状态1亮0灭在5ms的定时器中断逐个IO口扫描并且循环扫描点亮段码.1Pin10读取display_sram的bit15~bit12位如图中的B3 D3 F3 G3如果B3为1则Pin21点亮B3。2Pin20读取display_sram的bit11~bit8位 如图中的A3 B2 D2 E2如果B2为1则Pin31点亮B2。3Pin30读取display_sram的bit7~bit4位 如图中的C3 A2 C2 F2如果C3为1则Pin11点亮C3。4Pin40读取display_sram的bit3~bit0位 如图中的E3 C1 B1 G2如果B1为1则Pin31点亮B1。把段码数字和display_sram对应起来形成下列表格:例如数码管的个位要显示数字 0需要点亮 DIG3的B D F A C E六段即B3 D3 F3 A3 C3 E3为1其他段码为0对应的Hex值为0xE888代码#define PIN1_IN() TRISA21;//把单片机IO口配置为输入模式 #define PIN2_IN() TRISA31; #define PIN3_IN() TRISA41; #define PIN4_IN() TRISA51; #define PIN5_IN() TRISB01; #define PIN1_L() TRISA20;PA20;//把单片机IO口配置为输出模式输出低电平 #define PIN2_L() TRISA30;PA30; #define PIN3_L() TRISA40;PA40; #define PIN4_L() TRISA50;PA50; #define PIN5_L() TRISB00;PB00; #define PIN1_H() TRISA20;PA21;//把单片机IO口配置为输出模式输出高电平 #define PIN2_H() TRISA30;PA31; #define PIN3_H() TRISA40;PA41; #define PIN4_H() TRISA50;PA51; #define PIN5_H() TRISB00;PB01; /************************************************************************************/ void LED_GPIO_Init(void)//初始化IO口 { WPUA20;//关闭IO口的上拉电阻 WPUA30; WPUA40; WPUA50; WPUB00; PIN1_IN();//把单片机IO口配置为输入模式 PIN2_IN(); PIN3_IN(); PIN4_IN(); PIN5_IN(); } /********************************熄灭所有数码管***********************************/ void Set_AllPin_INPUT(void) { PIN1_IN(); PIN2_IN(); PIN3_IN(); PIN4_IN(); PIN5_IN(); } //在main函数中改变下列三个变量可以改变数码管的显示内容当前是显示124。 u8 bai1,shi2,ge4;//百位十位个位 u16 display_sram0; u16 Segment[3][11]{ {0x0000,0x0006,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000},//百位 {0x0770,0x0420,0x0741,0x0661,0x0431,0x0271,0x0371,0x0460,0x0771,0x0671,0x0000},//十位 {0xE888,0x8080,0xD808,0xD880,0xB080,0x7880,0x7888,0x8880,0xF888,0xF880,0x0000} //个位 }; void Display_Scan1(void) { PIN1_L();//拉低Pin1 if(display_sram0x8000) PIN2_H(); if(display_sram0x4000) PIN3_H(); if(display_sram0x2000) PIN4_H(); if(display_sram0x1000) PIN5_H(); } void Display_Scan2(void) { PIN2_L(); if(display_sram0x0800) PIN1_H(); if(display_sram0x0400) PIN3_H(); if(display_sram0x0200) PIN4_H(); if(display_sram0x0100) PIN5_H(); } void Display_Scan3(void) { PIN3_L(); if(display_sram0x0080) PIN1_H(); if(display_sram0x0040) PIN2_H(); if(display_sram0x0020) PIN4_H(); if(display_sram0x0010) PIN5_H(); } void Display_Scan4(void) { PIN4_L(); if(display_sram0x0008) PIN1_H(); if(display_sram0x0004) PIN2_H(); if(display_sram0x0002) PIN3_H(); if(display_sram0x0001) PIN5_H(); } /****************************显示函数***********************************/ //放在定时器中断函数5ms运行一次扫描一轮需要4*5ms20ms //也就是50Hz的刷新频率如果感觉闪烁可以4ms运行。 void Display_tube(void) { static u8 case_cnt;//逐行扫描 Set_AllPin_INPUT();//消影作用 display_sram0; display_sramSegment[0][bai] | Segment[1][shi] | Segment[2][ge];//显示百位十位个位 switch(case_cnt) { case 0x00:Display_Scan1();case_cnt;break; case 0x01:Display_Scan2();case_cnt;break; case 0x02:Display_Scan3();case_cnt;break; case 0x03:Display_Scan4();case_cnt0;break; default:case_cnt0;break; } }