找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2446|回复: 5
打印 上一主题 下一主题
收起左侧

8051单片机内部定时器/计数器程序问题

[复制链接]
跳转到指定楼层
楼主
实验设置8051单片机内部定时器/计数器T0计数,按方式2工作,对T0引脚(P3.4)手动输入的单脉冲进行计数。并将其计数值从P1口输出,在LED上显示出来。验证其正确性。输入我的代码后,小灯泡不亮,不知道哪里错了。求各位大佬告知
代码如下:#include<reg51.h>
#define uchar unsigned char
uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
uchar num=0;
void t0isr() interrupt 1
{
num++;
num%=10;
P1=table[num];
}
main()
{
TMOD=0x06;
TH0=0xff;
TL0=0xff;
TR0=1;
ET0=1;
EA=1;
while(1);
}

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:213173 发表于 2020-5-25 21:20 | 只看该作者
程序没有问题,只是初始化是少了一条P1=table[num];,但无关大局。


  1. #include<reg51.h>
  2. #define uchar unsigned char
  3. uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
  4. uchar num=0;

  5. void t0isr() interrupt 1
  6. {
  7.         num++;
  8.         num%=10;
  9.         P1=table[num];
  10. }
  11. void main()
  12. {
  13.         TMOD=0x06;
  14.         TH0=0xff;
  15.         TL0=0xff;
  16.         TR0=1;
  17.         ET0=1;
  18.         EA=1;
  19.         P1=table[num];
  20.         while(1);
  21. }
复制代码



回复

使用道具 举报

板凳
ID:94031 发表于 2020-5-25 21:22 | 只看该作者
//计数0计数,数码管显示,按键接P34
#include<reg51.h>
#define uchar unsigned char
uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
uchar num=0;

main()
{
        TMOD|=0x05;
        TR0=1;
       
        while(1)
        {
                num=TL0;
                P1=table[num];
                if(num>9){TL0=0;}
        }
}
回复

使用道具 举报

地板
ID:718035 发表于 2020-5-26 13:41 | 只看该作者
wulin 发表于 2020-5-25 21:20
程序没有问题,只是初始化是少了一条P1=table[num];,但无关大局。

多谢您的帮忙
回复

使用道具 举报

5#
ID:718035 发表于 2020-5-26 13:41 | 只看该作者
xuyaqi 发表于 2020-5-25 21:22
//计数0计数,数码管显示,按键接P34
#include
#define uchar unsigned char

多谢您的帮忙
回复

使用道具 举报

6#
ID:870180 发表于 2021-1-5 20:12 | 只看该作者
/**************************************************************************************
*                              LCD1602电子时钟                                                                                                  *
实现现象:下载程序后,LCD屏上第一行会显示出日期,第二行显示时间和当前温度。按下K1,进入时间调节
                 模式,按下K2让光标往左移,按下K3让光标处的数字增1,按下K4让光标处的数字减1
注意事项:                                                                                                                                                                  
***************************************************************************************/
//--头文件声明,数据类型声明--//
#include <reg52.h>
#include <intrins.h>
typedef unsigned char uint8;
typedef unsigned int uint16;

#define key P3
#define no_key 0xff                                        //无按键按下
#define key_state0 0                                //状态定义
#define key_state1 1
#define key_state2 2
//---------端口声明---------//
sbit lcden = P2^7;
sbit lcdrs = P2^6;
sbit lcdrw = P3^6;

sbit key1  = P3^2;
sbit key2  = P3^3;
sbit key3  = P3^4;
sbit key4  = P3^5;

sbit dq    = P3^7;                                        //DS18B20数据线
//---------函数声明---------//
void lcd_init();                                        //LCD屏幕初始化
void wcom();                                                //LCD写命令
void wdat();                                                //LCD写数据
void display();                                                //显示函数
void timeshow();                                        //时间显示
void dateshow();                                        //日期显示
void weekshow();                                        //星期显示
void keyscan();                                                //按键扫描
void key_disposal();                                //键值处理
void day_jud();                                                //日期处理
void ds18b20_init();                                //18B20模块初始化
uint8 byte_read();                                        //读去18B20一个字节
void byte_write();                                        //写入18B20一个字节
void temp_read();                                        //温度读取函数
void temp_display(uint8 position,uint16 tvalue1);                //温度显示函数
//---------变量定义---------//
uint8 time_1s,time_500ms;
uint8 second,minute = 59,hour = 23;
uint8 day = 1,month = 1,week = 1;                        //设定初始
uint16 year = 2019,tvalue;
//uint8 temp;
uint8 cursor;                                                                //要调节的位置
uint8 key_value;
bit f_twinkle,f_mode,f_pressing,f_set;

uint8 code table1[]={0x10,0x06,0x09,0x08,0x08,0x09,0x06,0x00};                        //字符℃


//---------长延时---------//
void delayms(uint16 k){
        uint16 i,j;
        for(i=k;i>0;i--)
                for(j=110;j>0;j--);
}

//---------短延时---------//
void delayus(uint8 time_1us){
        while(time_1us--);
}

//---------定时器初始化---------//
void timer_init(){
        EA = 0;
        TR0 = 0;
        TMOD = 0x01;
        TH0 = 0x4C;                //50ms
        TL0 = 0x00;

        ET0 = 1;                //允许Timer0中断
        ET1 = 1;
        EA  = 1;
        TR0 = 1;
}

//---------Timer0中断服务函数---------//
void isr_timer0 () interrupt 1 using 0 {
        TH0 = 0x4C;                //50ms
        TL0 = 0x00;
        keyscan();
        if(++time_500ms >= 10){
                time_500ms = 0;
                f_twinkle = ~f_twinkle;
        }
        if(!f_set){
                if(++time_1s >= 20){
                        time_1s = 0;
                        second++;
                }
        }
}

void ds18b20_init(){                                                //ds18b20初始化
        dq = 1;       
        _nop_();
        dq = 0;
        delayus(75);
        dq = 1;
        delayus(20);
        dq = 1;
        _nop_();
}

void wcom(uint8 com){                                                //LCD1602写命令
        lcdrw = 0;
        lcdrs = 0;
        P0 = com;
        lcden = 1;
        delayms(3);
        lcden = 0;
}

void wdat(uint8 dat){                                                //LCD1602写数据
        lcdrw = 0;
        lcdrs = 1;
        P0 = dat;
        lcden = 1;
        delayms(3);
        lcden = 0;       
}

void lcd_init(){                                                        //LCD初始化
        wcom(0x38);
        wcom(0x01);
        wcom(0x06);
        wcom(0x0c);
       
        wcom(0x86);
        wdat(0x2d);                                                                //"-"
        wcom(0x89);
        wdat(0x2d);                                                                //"-"
        wcom(0x80+0x40+0x04);
        wdat(0x3a);                                                                //":"
        wcom(0x80+0x40+0x07);
        wdat(0x3a);                                                                //":"
}

void timeshow(uint8 position,uint8 time){                //时间显示,position为显示位置
        uint8 i,j;
        i = time/10;                                //shiwei
        j = time%10;                                //gewei
        wcom(0x80+0x40+position);
        wdat(0x30+i);                                //shiwei
        wdat(0x30+j);                                //gewei
}

void dateshow(uint8 position,uint8 date1){                //日期显示(月、日)
        uint8 i,j;
        i = date1/10;                                //shiwei
        j = date1%10;                                //gewei
        wcom(0x80+position);
        wdat(0x30+i);                                //shiwei
        wdat(0x30+j);                                //gewei
}

void yearshow(uint8 position,uint16 year1){                //年份显示
        uint8 i,j,m,n;
        i = year1/1000;                                //qianwei
        j = year1/100%10;                        //baiwei
        m = year1/10%10;
        n = year1%10;
        wcom(0x80+position);
        wdat(0x30+i);                                //qianwei
        wdat(0x30+j);                                //baiwei
        wdat(0x30+m);                                //shiwei
        wdat(0x30+n);                                //gewei
}

void weekshow(uint8 position,uint8 week1){                //星期显示
        wcom(0x80+position);
        switch(week1){
                case 1:wdat(0x4d);wdat(0x4f);wdat(0x4e);break;
                case 2:wdat(0x54);wdat(0x55);wdat(0x45);break;
                case 3:wdat(0x57);wdat(0x45);wdat(0x44);break;
                case 4:wdat(0x54);wdat(0x48);wdat(0x55);break;
                case 5:wdat(0x46);wdat(0x52);wdat(0x49);break;
                case 6:wdat(0x53);wdat(0x41);wdat(0x54);break;
                case 7:wdat(0x53);wdat(0x55);wdat(0x4e);break;
                default:break;
        }
}

void day_jud(){                                                                        //日期处理(秒、分、时、日、月进位)
        if(second > 59){
                second = 0;
                if(++minute > 59){
                        minute = 0;
                        if(++hour > 23){
                                hour = 0;
                                if(++week >= 8)        week = 1;
                                day++;
                        }
                }
        }
       
        if(minute > 59){
                minute = 0;
                if(++hour > 23){
                        hour = 0;
                        if(++week > 7)        week = 1;
                        day++;
                }
        }
       
        if(hour > 23){
                hour = 0;
                if(++week > 7)        week = 1;
                day++;
        }
       
        if(day > 31 && (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12)){
                day = 1;
                month++;
                if(month >= 12){
                        month = 1;
                        year++;
                }
        }
        else if(day > 30 && (month == 4 || month == 6 || month == 9 || month == 11)){
                day = 1;
                month++;
        }
        else if(day > 29 && month == 2 && ((year%4 == 0 && year%100 != 0) || year%400 == 0)){
                day = 1;
                month++;
        }
        else if(day > 28 && month == 2){
                day = 1;
                month++;
        }
}

void display(){                                                                                //显示函数
        if(!f_mode){                                                                        //时间显示模式
                yearshow(2,year);
                dateshow(7,month);
                dateshow(0x0a,day);
                weekshow(0x0d,week);
               
                timeshow(2,hour);
                timeshow(5,minute);
                timeshow(0x08,second);
                temp_read();                                                                //读取温度
                temp_display(0x0b,tvalue);                                        //温度显示
        }
        else{                                                                                        //时间调节模式
                wcom(0x80+0x40+0x0d);
                wdat(0x53);                                                                        //"S"
                wdat(0x45);                                                                        //"E"
                wdat(0x54);                                                                        //"T"

                if(f_twinkle && !f_pressing){                                //闪烁标志位,0.5秒取反一次,为1则相应位置显示空白
                        if(cursor == 0) {                                                //按压标志位,按键按下时为1,不闪烁
                                wcom(0x82);                                                        //要显示空白的位置
                                wdat(0x20);                                                        //4位空白(实现闪烁效果)
                                wdat(0x20);
                                wdat(0x20);
                                wdat(0x20);
                        }
                        if(cursor == 1) {
                                wcom(0x87);                                                        //要显示空白的位置
                                wdat(0x20);                                                        //2位空白
                                wdat(0x20);
                        }
                        if(cursor == 2) {
                                wcom(0x8a);
                                wdat(0x20);
                                wdat(0x20);
                        }
                        if(cursor == 3) {
                                wcom(0x8d);
                                wdat(0x20);
                                wdat(0x20);
                                wdat(0x20);
                        }
                        if(cursor == 4) {
                                wcom(0x80+0x42);
                                wdat(0x20);
                                wdat(0x20);
                        }
                        if(cursor == 5) {
                                wcom(0x80+0x45);
                                wdat(0x20);
                                wdat(0x20);
                        }
                        if(cursor == 6) {
                                wcom(0x80+0x48);
                                wdat(0x20);
                                wdat(0x20);
                        }
                }
                else {                                                                                //正常显示
                        yearshow(2,year);
                        dateshow(7,month);
                        dateshow(0x0a,day);
                        weekshow(0x0d,week);
                        timeshow(2,hour);
                        timeshow(5,minute);
                        timeshow(0x08,second);
                }
        }
}

void keyscan(){                                                                                //按键扫描
        static uint8 key_state;
       
        switch(key_state){
                case key_state0:                                                        //未按下
                        if(!key1 || !key2 || !key3 || !key4){
                                key_state = key_state1;
                        }
                break;
                case key_state1:                                                        //有键按下
                        f_pressing = 1;
                        if(!key1){
                                f_set = ~f_set;                                                //秒走时停止
                                f_mode = ~f_mode;                                        //模式切换
                                key_value = 1;
                                key_state = key_state2;
                        }
                        else if(!key2){
                                key_value = 2;
                                key_state = key_state2;
                        }
                        else if(!key3){
                                key_value = 3;
                                key_state = key_state2;
                        }
                        else if(!key4){
                                key_value = 4;
                                key_state = key_state2;
                        }
                        else{
                                key_state = key_state0;
                                f_pressing = 0;                                                //如果不清零,假如按键是无效按下,调节模式时就会停止闪烁
                        }
                break;
                case key_state2:                                                        //松开按键
                        if(key1 && key2 && key3 && key4){
                                f_pressing = 0;
                                key_state = key_state0;
                        }
                break;
        }
}

void key_disposal(){                                                                //键值处理
        if(!f_pressing){                                                                //松开按键才处理
                if(key_value == 1){
                        key_value = 0;
                        cursor = 0;                                                                //光标位置清零
                        lcd_init();                                                                //清屏
                }
                else if(key_value == 2){
                        key_value = 0;
                        cursor++;                                                                //光标+(光标即闪烁的位置,实际上LCD上并无光标)
                        if(cursor > 6){
                                cursor = 0;
                        }
                }
                else if((key_value == 3) && f_mode){                //光标所处位置值+
                        key_value = 0;
                        if(cursor == 0){
                                year++;
                        }
                        else if (cursor == 1){
                                if(++month > 12) month = 1;
                        }
                        else if(cursor == 2){
                                if(++day > 31) day = 1;
                        }
                        else if(cursor == 3){
                                if(++week > 7) week = 1;
                        }
                        else if(cursor == 4){
                                if(++hour > 23) hour = 0;
                        }
                        else if(cursor == 5){
                                if(++minute > 59) minute = 0;
                        }
                        else if(cursor == 6){
                                if(++second > 59) second = 0;
                        }
                }
                else if((key_value == 4) && f_mode){                //光标所处位置值-
                        key_value = 0;
                        if(cursor == 0 && year > 0){
                                year--;
                        }
                        else if (cursor == 1 && month > 1){
                                month--;
                        }
                        else if(cursor == 2 && day > 1){
                                day--;
                        }
                        else if(cursor == 3 && week > 1){
                                week--;
                        }
                        else if(cursor == 4 && hour > 0){
                                hour--;
                        }
                        else if(cursor == 5 && minute > 0){
                                minute--;
                        }
                        else if(cursor == 6 && second > 0){
                                second--;
                        }
                }
        }
}

uint8 byte_read(){                                                                        //ds18b20 读字节
        uint8 i,j,dat;
        for(i = 0; i < 8 ; i++){
                dq = 0;
                _nop_();
                dq = 1;
                _nop_();
                j = dq;
                delayus(10);
                dq = 1;
                _nop_();
                dat = (j << 7 | dat >> 1);
        }
        return(dat);
}

void byte_write(uint8 data1){                                                //ds18b20 写字节
        uint8 i;
        for(i = 0; i < 8 ; i++){
                dq = 0;
                _nop_();
                dq = data1&0x01;
                delayus(10);
                dq = 1;
                _nop_();
                data1 >>= 1;
        }
}

void temp_read(){                                                                        //读温度
        float data1;
        uint8 i,j;
        ds18b20_init();
        byte_write(0xcc);                                                                //向DS18B20发跳过读ROM命令
        byte_write(0x44);                                                                //启动DS18B20进行温度转换命令,转换结果存入内部RAM
        delayus(80);
        ds18b20_init();
        byte_write(0xcc);                                                                //向DS18B20发跳过读ROM命令
        byte_write(0xbe);                                                                //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
        delayus(80);
        i = byte_read();                                                                //内部RAM 低位
        j = byte_read();                                                                //内部RAM 高位
        data1 = (j*256 + i) * 6.25;                                                //取出温度值
        tvalue = (uint16)data1;                                                        //强制转换
}

void temp_display(uint8 position,uint16 tvalue1){        //温度显示
        uint8 i,j,m;
        i = tvalue1/1000;
        j = tvalue1%1000/100;
        m = tvalue1%100/10;                                                                //取出十位 个位 十分位
        wcom(0x80 + 0x40 + position);
        wdat(0x30 + i);
        wdat(0x30 + j);
        wdat(0x2e);                                                                                //"."
        wdat(0x30 + m);
        wdat(0x00);                                                                                //自编字符
}

void main(){
        uint8 i;
        wcom(0x40);
        for(i = 0; i < 8 ; i++){
                wdat(table1[i]);                                                        //写入自编字符
        }
       
        timer_init();
        lcd_init();
        while(1){
                // if(++temp > 2){
                        // temp = 0;
                // }
                // switch(temp){
                        // case 0:day_jud();break;
                        // case 1:key_disposal();break;
                        // case 2:display();break;
                // }
                day_jud();
                key_disposal();
                display();
        }
}


仿真出来了,然后连上lcd只有第二行黑格,其他数字都没有呀,楼主,咋回事哦。求解,谢谢,
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表