![]() |
你确定首发的图正确?CPU处是P0口输出数据,数码管处是用了p0;p1???? |
hjx5548 发表于 2025-1-24 05:11 //====主函数============================================== void main() { P1M0 = 0x00; P1M1 = 0x00; P3M0 = 0x00; P3M1 = 0x00; P5M0 = 0x00; P5M1 = 0x00; while(1) { display_out(34); Delay5ms(); } } |
hjx5548 发表于 2025-1-24 05:11
|
hjx5548 发表于 2025-1-24 05:11 为何要做定时器中断里面调用display_out(34);? |
hjx5548 发表于 2025-1-24 05:11 发原理图全图 |
hjx5548 发表于 2025-1-24 07:55 上传代码要用代码功能,就是上边的那个中括弧 |
segment_out(duan_ma[date[i]]);//上传怎么没有了 |
WL0123 发表于 2025-1-23 14:55 #include "STC8G.h" #include <intrins.h> #define uint unsigned int #define uchar unsigned char //----I/O口段定义----------------------------------- sbit da=P3^7; sbit db=P3^2; sbit dc=P3^3; sbit dd=P3^5; sbit de=P3^4; sbit df=P3^6; sbit dg=P1^1; sbit dp=P1^0; //不含小数点8段LED字形码0-9+黑屏码、共阳极驱动0亮1熄 uchar duan_ma[11]= {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff}; uchar date[4];//显示数据暂存 bit flag; void Delay1ms(void) //@11.0592MHz { unsigned char data i, j; i = 15; j = 90; do { while (--j); } while (--i); } void Timer0_Init(void) //1毫秒@12.000MHz { AUXR |= 0x80; //定时器时钟1T模式 TMOD &= 0xF0; //设置定时器模式 TL0 = 0x20; //设置定时初始值 TH0 = 0xD1; //设置定时初始值 TF0 = 0; //清除TF0标志 TR0 = 1; //定时器0开始计时 ET0=1; EA=1; } //======================================================= //将LED字形的8个笔段控制I/O引脚映射到变量的8个位上 void segment_out(uchar dat) { da=(bit)(dat&0x01); db=(bit)(dat&0x02); dc=(bit)(dat&0x04); dd=(bit)(dat&0x08); de=(bit)(dat&0x10); df=(bit)(dat&0x20); dg=(bit)(dat&0x40); dp=(bit)(dat&0x80); } //====数据拆分函数======================================= //提取出数据的千、百、十、个位的数值存入数组中 void digits_obtain(uint dat) { date[0]=dat/10; date[1]=dat%10; } //====显示输出函数======================================= void display_out(uint dat) { static uchar i; digits_obtain(dat);//拆分数据 segment_out(0xff);//段码清除(消隐) if(i==0) {P55=0;P12=1;}//十位 else {P55=1;P12=0;}//个位 segment_out(duan_ma[date]);//发送段显示码 // i=++i%2; if (++i>=2) i=0; } //====主函数============================================== void main() { P1M0 = 0x00; P1M1 = 0x00; P3M0 = 0x00; P3M1 = 0x00; P5M0 = 0x00; P5M1 = 0x00; Timer0_Init(); Delay1ms(); while(1) { if(flag)//5ms { flag=0; // display_out(34); } } } void Timer0Interrupt(void) interrupt 1 { display_out(34); flag=1; } 还是显示9 |
WL0123 发表于 2025-1-23 14:55 端口模式已经设置void main() { P1M0 = 0x00; P1M1 = 0x00; P3M0 = 0x00; P3M1 = 0x00; P5M0 = 0x00; P5M1 = 0x00; |
//====显示输出函数======================================= void display_out(uint dat) { static uchar i; digits_obtain(dat);//拆分数据 segment_out(0xff);//段码清除(消隐) if(i==0) {P55=0;P12=1;}//十位 else {P55=1;P12=0;}//个位 segment_out(duan_ma[date]);//发送段显示码 i=++i%2; } 还是一样 |
hjx5548 发表于 2025-1-23 07:04 如果MCU采用的还是STC12C5A60S2不需要设置端口模式,默认是准双向。没有P55,就在P50~53选一个空闲脚或其它空闲脚。你那十位显示9其实是3和4的叠加。换芯片STC8G1K08,需要设置端口模式,因为默认是高阻。定时器用自动重装模式为好。上述两款单片机可以直接驱动数码管,不需要加晶体管放大。数码管段驱动要加8个限流电阻。 |
![]() ![]() |
WL0123 发表于 2025-1-22 11:30 修改一下,十位显示9,个位无显示。 /*hjx5548 发表于 2025-1-21 22:13 如果这样怎么修改 如果MCU采用的还是STC12C5A60S2那就没有P55,只有P50~53。示例程序:*/ //#include <STC12C5A60S2.h> #include "STC8G.h" #include <intrins.h> #define uint unsigned int #define uchar unsigned char //----I/O口段定义----------------------------------- sbit da=P3^7; sbit db=P3^2; sbit dc=P3^3; sbit dd=P3^5; sbit de=P3^4; sbit df=P3^6; sbit dg=P1^1; sbit dp=P1^0; //不含小数点8段LED字形码0-9+黑屏码、共阳极驱动0亮1熄 uchar duan_ma[11]= {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff}; uchar date[4];//显示数据暂存 bit flag; void Timer0_Init(void) //5毫秒@11.0592MHz { AUXR |= 0x80; //定时器时钟1T模式 TMOD &= 0xF0; //设置定时器模式 TL0 = 0x00; //设置定时初始值 TH0 = 0x28; //设置定时初始值 TF0 = 0; //清除TF0标志 TR0 = 1; //定时器0开始计时 ET0=1; EA=1; } //======================================================= //将LED字形的8个笔段控制I/O引脚映射到变量的8个位上 void segment_out(uchar dat) { da=(bit)(dat&0x01); db=(bit)(dat&0x02); dc=(bit)(dat&0x04); dd=(bit)(dat&0x08); de=(bit)(dat&0x10); df=(bit)(dat&0x20); dg=(bit)(dat&0x40); dp=(bit)(dat&0x80); } //====数据拆分函数======================================= //提取出数据的千、百、十、个位的数值存入数组中 void digits_obtain(uint dat) { date[0]=dat/10; date[1]=dat%10; } //====显示输出函数======================================= void display_out(uint dat) { static uchar i; digits_obtain(dat);//拆分数据 segment_out(0xff);//段码清除(消隐) if(i==0) {P55=0;P12=1;}//十位 else {P55=1;P12=0;}//个位 segment_out(duan_ma[date]);//发送段显示码 i=++i%2; } //====主函数============================================== void main() { P1M0 = 0x00; P1M1 = 0x00; P3M0 = 0x00; P3M1 = 0x00; P5M0 = 0x00; P5M1 = 0x00; Timer0_Init(); while(1) { if(flag)//5ms { flag=0; display_out(34); } } } void Timer0Interrupt(void) interrupt 1 { TL0 = 0x00; //设置定时初始值 TH0 = 0x28; //设置定时初始值 flag=1; } |
WL0123 发表于 2025-1-22 11:30 芯片是STC8G1K08 |
hjx5548 发表于 2025-1-21 22:13 如果MCU采用的还是STC12C5A60S2那就没有P55,只有P50~53。示例程序:
|
xiaobendan001 发表于 2025-1-16 12:46 这个我试了,你是对的,没有错 |
数码管显示异常是楼主的数码管位驱动码错误所致。修改如下:
|
jjy1039 发表于 2025-1-16 08:59 有没有试过?软件模拟也能看到的 |
da=(bit)(duan_ma[dat]&0x01); ....... |
单片机研究协会 发表于 2025-1-16 01:10 位域怎么写,请大侠指点一二 |
1、先排除掉硬件问题,接线问题。2、直接用高低电平试试每一段是不是都能点亮。然后用程序控制。逻辑上不要有冲突。 |
新爱的坛友,你确定你的代码没有问题吗!你确定你已经编译通过了吗! LINE 96 segment_out(duan_ma[date]); //发送段显示码 LINE 97 position_out(wei_ma); //发送位显示码 这两行代码重点检查一下...... |
segment_out(duan_ma[date]); //发送段显示码 [date] 默认是地址 0 ,所以只显示0 修改:date[i] |
96行, segment_out(duan_ma[date]); 其中date是数组类型,改为segment_out(duan_ma[i ]) |
DATE是个数组,你把它当做下标是几个意思。你是不是应该这样duan_ma[date[i]]; 还有wei_ma也有问题。是不是也应该写成wei_ma[i];, |
有两点可以优化 1:改用共阴数码管,可以省三极管 2:改用位域操作 |