蓝桥杯单片机易错点(深夜学习——单片机)

蓝桥杯单片机易错点(深夜学习——单片机)蓝桥杯单片机易错点_icm230602寄存器默认为

一、使用标志位时记得在判断成功后清除标志位

        if(count == 500)
        {
            sprintf(SEG_COT, "%4u--%02u", year,(u16)month);
            SEG_TSL(SEG_COT,SEG_Code);
            if(month == 12)
                month = 0;
            month++; 
            count = 0;
     }

二、使用定时器前记得初始化定时器,用STC-ISP生成定时器初始化时记得开中断

三、除了主函数外的函数,局部变量必须显式初始化

当你定义一个局部变量时,编译器会从堆栈中分配一定的内存给这个局部变量,而这个局部变量的初值是否为”0“我们是不能保证的,因为分配内存的地址是随机的,这个地址可能是其他函数用过的或者是第一次进入本函数用过的(这时候局部变量就相当于静态局部变量了)

例:

/*
    输入变量:num,一个小于65535的数;D_num,存放分割好数据的数组
    输出变量:
    功能:将一个小于65535数的每一位分割出来
*/
void SEG_TSL(u8 *input,u8 *output)
{
    u8 i=0,temp=0,j;
    for(i=0;i<8;i++,j++)
    {
        switch(input[j])
        {
            case '0': temp = 0xc0; break;
      case '1': temp = 0xf9; break;
      case '2': temp = 0xa4; break;
      case '3': temp = 0xb0; break;
      case '4': temp = 0x99; break;
      case '5': temp = 0x92; break;
      case '6': temp = 0x82; break;
      case '7': temp = 0xf8; break;
      case '8': temp = 0x80; break;
      case '9': temp = 0x90; break;
      case 'A': temp = 0x88; break;
      case 'B': temp = 0x83; break;
      case 'C': temp = 0xc6; break;
      case 'D': temp = 0xA1; break;
      case 'E': temp = 0x86; break;
      case 'F': temp = 0x8E; break;
      case 'H': temp = 0x89; break;
      case 'L': temp = 0xC7; break;
      case 'N': temp = 0xC8; break;
      case 'P': temp = 0x8c; break;
      case 'U': temp = 0xC1; break;
      case '-': temp = 0xbf; break;
      case ' ': temp = 0xff; break;
      default: temp = 0xff;
        }
        if(input[j+1] == ".")
        {
            temp &= 0x7f;
            j++;
        }
        output[i] = temp;
    }
}

我们可以看到定义的j变量,由于我一开始没有对它置数导致j就在一直累加,而在我当时的想法它只是一个局部变量,初值一定为”0″,然后我就大错特错了。

四、除了自己事先编写好的函数要引用,我们现场写的具体功能的函数也要记得引用,例如:按键检测的函数

五、并不是所有寄存器上电后都默认为0x00,AUXR辅助寄存器上电后默认为0x01

六、“\0”不等于‘\0′

void Uart_1_TX_String(u8 *S_dat)
{
    while(*S_dat != "\0")
    {
        SBUF = *S_dat;
        while(TI == 0);
        TI = 0;
        S_dat++;
    }
}

本来while中我是想判断当传入数据为空字符时跳出的,但是用了双引号表示字符串而不是字符,判断就出错了,然后我就想看看“\0”是什么,结果好像是乱码

蓝桥杯单片机易错点(深夜学习——单片机)

七、数码管易错点:

1.分配时间变量要定义为unsigned int类型

    //分配工作时间
    if(SEG_delay++ == 1000) SEG_delay = 0;
    if(DS1302_delay++ == 400) DS1302_delay = 0;

2.使用stp生成定时器代码时记得加上开启中断代码

void Timer0_Init(void)        //1毫秒@12.000MHz
{
    AUXR &= 0x7F;            //定时器时钟12T模式
    TMOD &= 0xF0;            //设置定时器模式
    TL0 = 0x18;                //设置定时初始值
    TH0 = 0xFC;                //设置定时初始值
    TF0 = 0;                //清除TF0标志
    TR0 = 1;                //定时器0开始计时
    //开启中断
    ET0 = 1;
    EA = 1;
}

3.sprintf函数使用要注意类型的前后对应,而且最后”%u-%u-%u”与最后显示的格式是一一对应的


sprintf(SEG_COT,"%u-%u-%u",(u16)DS1302_time[2],(u16)DS1302_time[1],(u16)DS1302_time[0]);

八、置零用“&”,置一用“|”

九、由于蓝桥杯板子使用锁存器控制多个设备,所以P0会被多次使用,如果要使用上一次P0数据进行处理,记得事先保存,如:

/*
    将蜂鸣器电平置位
*/
void Buzzer_Turn(u8 turn_num)
{
    if(turn_num == 1)
        P0 = last_R_B | (0x01<<6);
    else if(turn_num == 0)
        P0 = last_R_B & (~(0x01<<6));
    last_R_B = P0;    
    P2 = P2 & 0x1f | 0x50<<1;
    P2 &= 0x1f;
}

十、define是将后面的定义位前面的

今天的文章蓝桥杯单片机易错点(深夜学习——单片机)分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/84622.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注