写KeilC遇到的坑

1、跟vs中不同,keilC中的的变量必须声明在最前,不然就出错。

2、KeilC中的错误提示功能实在是很弱。没有办法精确到具体是哪个具体的变量或标点符号出问题。

3、KeilC中的unsigned int能表示的数太小,只能有五位数,导致烧到单片机上的时候,数码管显示有问题。

unsigned char,8位,最大值255
unsigned int,16位,最大值65535

4、8针的引脚只要用unsigned char就可以控制,因为unsigned char 是8位的。

5、在LCD1602输出了脏数据。

 1 #include<reg51.h>
 2 #define uchar unsigned char
 3 #define uint unsigned int
 4 uchar code table[]="Hello World!";
 5 uchar code table1[]="I am a boy!";
 6 ///此处省略了一系列的函数定义
 7 void main()
 8 {
 9         int num;
10     init();
11     write_command(0x80+0x10);
12     for(num=0;num<20;num++)
13     {
14         write_data(table[num]);
15         delay(5);
16     }
17     //此处省略了一些无关内容
18 }

在以上代码段中,我们期望在LCD1602的第一行输出"Hello World!       ",注意这个输出后面是空白的,但是输出了"Hello World!       **** I am a"(***代表乱码)。这就有点无奈了。调了好久,一开始以为是ram里面有暂存的数据,单片机断电后,再试还是不行。后面联想到编译原理中,两个字符串table和table1都是用code定义的数组,他们存储位置是程序存储器。又因为table1定义的位置正好在table的下面,所以当以上代码行12对应处遍历table数组超出table本身的索引时,自然就输出了table1的内容,从而造成脏数据。

 

6、头文件的定义。

①当我们定义头文件的时候,最后不要在头文件里面定义define uchar unsigned char 这类的东西,因为当引用了两次头文件或者不同的头文件里面都有同样的define的时候,程序会出问题。

②当定义头文件的时候,为了避免二次引用造成重复定义,最好在头文件上#ifndef __I2C_H__、  #define __I2C_H__ 、#endif(其中__I2C_H__是自己定义的一个名称)如以下代码段所示。参考链接

 

 1 #ifndef __I2C_H__
 2 #define __I2C_H__
 3
 4 //========函数区============================================
 5 extern void I2C_start();  //开始信号
 6 extern void I2C_stop();   //停止
 7 extern void I2C_respons();  //应答
 8 extern void I2C_write_byte(unsigned char date);
 9 extern unsigned char I2C_read_byte();
10 extern void I2C_write_address(unsigned char address,unsigned char date);
11 extern unsigned char I2C_read_address(unsigned char address);
12 //========函数区结束============================================
13 #endif

 

 7、按键反应很慢。

下面的程序是一个按下独立按键,然后在LED屏幕上显示当前计数值的程序。程序要实现:当按下独立按键1的时候,等待。当再次按下,程序往下运行。我发现当我按下,程序可以很快地反应;但是再次按下想让他运行的时候,却要等待大概3~5秒的时间。细看以下代码段加灰的地方和中断函数,终于发现了原因。原来,当忙等待的时候,中断函数int0()中的Count还在不断计数,也就是Count可能大于20,那么就不满足Count==20这个条件。而要等再次满足Count==20,则要等待Count计满重新归零(注意Count是无符号数,无符号数计满的时候自动归零)。

#include<reg51.h>
unsigned char Count=0;
/***********************************************************
    重新计数
***********************************************************/
void ReCount(){
    Count=0;  //开始下一轮1s的计时
    TH0=T_High_50ms;// 计算初值,并将其写入TH0、TL0或TH1、TL1。
    TL0=T_Low_50ms;
}
void main()
{//去掉不必要的初始化函数
    while(1){
Waiting();//一个忙等待函数,当按下独立按键1的时候,等待。当再次按下,
        //程序往下运行
        if(Count==20){//定时器0 1s时间到
                    ReCount();
                    //……省略做其他事情的函数
                }
            }
}
void int0() interrupt 1//定时/计数器T0中断
{
    Count++;
}

 8、强制转化的问题

除了强制转化成bit型是取高位外(代码段1),其他从位数少到位数多类型的强制类型转换都是取低位。

 1 unsigned char aChar=0x00;//除了强制转化成bit型是取高位外
 2 unsigned int aInt=0xaa55;
 3 aChar=(unsigned char)aInt;
 4 //结果:aChar=0x55
 5
 6 ///////////////////////////////////////////////////////////////
 7 bit aBit;
 8 unsigned char aChar=0x01; //其他从位数少到位数多类型的强制类型转换都是取低位。
 9 aBit=(bit)aChar;
10 //结果:aBit=0;

9、全局变量定义在头文件(*.h)或源文件(*.c)的思考。

看了一些代码,似乎在头文件的定义中都尽量地避免了对全局变量的定义。我想头文件是给人引用的,也就是这部分的内容必须暴露,为了函数的封装性更好,更好的方法就是将全局变量尽可能封装在源文件 (*.c)。这样,使用者不会因为头文件中含有全局变量而感到困惑,也不用因为全局变量而去了解整个C语言函数库的实现细节。

10、C#和Java都是支持函数的重载的,但是C语言中不支持函数的重载。

1 int add(int a,int b);             //函数1
2 int add(int a,int b,int c);       //函数2

C语言中,如果你定义了函数1,那么就不能再定义函数2.不然编译就不通过了。究其原因,可能是因为C语言中有函数指针这东西(见一下代码段,重载会让C编译器不知道将哪个函数地址赋给函数指针)。

#include <stdio.h>
int add(int a,int b);
//int add(int a , int b , int c);
int sub(int a,int b);
void result(int (* pf)() , int a , int b);
main(){
   int i,j=1;
   int (* pf)();
   pf=add;        //这里如果重载了add函数,那么这里编译器就不知道要把哪个add
   result(pf,i,j);//赋值给pf
   pf=sub;
   result(pf,i,j);
}

int add(int a , int b){
     return a+b;
}
int sub(int a,int b){
     return a-b;
}
void result(int (*pf)() , int a , int b){
   int value;
   value = (*pf)(a , b);
   printf("%d\t",value);
}

 

 

作者:kissazi2 
出处:http://www.cnblogs.com/kissazi2/ 
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

转载:http://www.cnblogs.com/kissazi2/archive/2013/05/25/3098325.html

时间: 2024-09-28 12:12:42

写KeilC遇到的坑的相关文章

如何实现自己没实现过的需求之文本动画

前言 记得以前看到过一个很赞的文字效果的动画,类似于这样: 当时被惊艳到了,最近偶然间又再次见到,依然还是那么喜欢.假设我们现在需要实现这样的需求.一般碰到需求我们都会去 GitHub 上看看,俗称找轮子(GitHub 基本上只有你想不到的,就没有它没有的).大多数情况下,没有问题.或者说有点小问题:轮子太多,无从下嘴. 选择 选轮子就像选姑娘,你不知道后面等着你的是什么 -–罪恶坑小程如是说 程序员江湖,每位大侠的武功和套路不尽一样,少林,武当,昆仑各门各派,百花争艳.实现轮子的思路自然也不一

请教SOCKET 服务端代码

问题描述 //监听函数publicvoidListen(){//初始化SOCKET实例newsock=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);//初始化终结点实例localEP=newIPEndPoint(IPAddress.Any,setPort);try{//绑定newsock.Bind(localEP);//监听newsock.Listen(10);//用于设置按钮状态m_Listen

Hadoop+Spark+MongoDB+MySQL+C#大数据开发项目最佳实践

随着IT技术的飞速发展,各行各业都已在广泛尝试使用大数据技术提供更稳健和优质的服务.目前,医疗IT系统收集了大量极具价值的数据,但这些历史医疗数据并没有发挥出其应有的价值.为此,本文拟利用医院现有的历史数据,挖掘出有价值的基于统计学的医学规则.知识,并基于这些信息构建专业的临床知识库,提供诊断.处方.用药推荐功能,基于强大的关联推荐能力,极大地提高医疗服务质量,减轻医疗人员的工作强度.   二.Hadoop&Spark  目前大数据处理领域的框架有很多.   从计算的角度上看,主要有MapRed

亲密接触Redis-第一天

引言 nosql,大规模分布式缓存遍天下,Internet的时代在中国由其走得前沿,这一切归功于我国特色的电商.因此nosql.大数据技术在中国应用的比国外还要前沿.从这一章开始我们将开始进入到真正的SOA.PAAS.SAAS.互联网的领域,因此每一篇我都会加入一小段业务的基础知识,让大家在学习技术的同时也可以了解一些业务,这边的业务不是指的business logic不是让大家去做业务人员,而是为大家带来IDEA,"没有做不到只有想不到",阿里支付宝为什么发了...不是技术,而是它的

我创业所经历的那些故事

第一篇 2011年春节过后,公司里来了一个实习的小伙子,是一个朋友的弟弟,他来我公司给我做的第一个工作是做了一个网站.同时还来了一个实习的小姑娘,那小姑娘技术一点都不懂,没过几天就走了.我印象最为深刻的是,开发区来检查我的办公环境,因为前一年我申请了开发区的创业资助.后来,我拿里开发区的创业资助,我想还是挺幸运的. 办公室里那个小伙子,好像喜欢那个小姑娘,那个小姑娘后来没有来上班,我觉得那小伙子要负一定的责任.这么小的公司,总共三个人,发生点办公室恋情,是不是很正常?(请不要介意,我只是八卦一下

从临危授命到扭转乾坤,天天拍车运维架构演进及实践

从临危授命到扭转乾坤,天天拍车运维架构演进及实践 李强 2017-04-24 11:52:24 本文根据李强老师在[4月8日DBAplus社群上海数据库技术沙龙]现场演讲内容整理而成.点击文末链接还能下载PPT哦~   讲师介绍  李强 天天拍车运维总监   网名:撒加,先后在AdMaster.饿了么担任运维经理,现任天天拍车运维总监,主要负责天天拍车运维架构的管理.持续优化以及运维团队的建设.培养. 9年以上运维及管理经验.作为国内最早一批思科网络模拟器的推广者.虚拟化先锋论坛的创始人,一直致

Hadoop+Spark 大数据开发项目最佳实践

随着IT技术的飞速发展,各行各业都已在广泛尝试使用大数据技术提供更稳健和优质的服务.目前,医疗IT系统收集了大量极具价值的数据,但这些历史医疗数据并没有发挥出其应有的价值.为此 ,本文拟利用医院现有的历史数据,挖掘出有价值的基于统计学的医学规则.知识,并 基于这些信息构建专业的临床知识库,提供诊断.处方.用药推荐功能,基于强大的关联推荐能力,极大地提高医疗服务质量,减轻医疗人员的工作强度. 二.Hadoop&Spark 目前大数据处理领域的框架有很多. 从计算的角度上看,主要有MapReduce

【微框架】Maven +SpringBoot 集成 阿里大鱼 短信接口详解与Demo

Maven+springboot+阿里大于短信验证服务 纠结点:Maven库没有sdk,需要解决 Maven打包找不到相关类,需要解决 一.本文简介 在工作当中的项目中,我遇到过这种情况,公司架构选型SpringBoot ,这是个基于Maven构建的项目, 需要集成阿里大鱼短信系统,然后暴露REST风格的API接口出去.本文重点讲解. 二.开发准备 阿里大于,是阿里的通讯产品之一,提供短信验证码服务. 1.需要注册阿里大鱼账户.充值.设置,这一块不多讲,官网有文档. (https://www.a

2015年年中总结暨2016年全年计划 ----#天生骄傲#

终于盼到年末的最后一天,此时此刻的我跟去年今天的我一样坐在电脑前总结一年的得与失,遥望星空与脚踏实地.2015年是一个不平凡的一年,2015年是一个丰硕的一年也是一个损失的一年.这一年既有辛苦开心的汗水也有男儿有泪不轻弹的泪水,真情的泪水让我更加懂得珍惜现在拥有的.有时候我们也在问自己我们这么拼命的工作跻身中上层社会是为了什么?为的不就是让自己亲人更好的物质生活.下面总结一下自己的方方面面.这个是我的2014年总结:2014年感想总结 - 满招损,谦受益. - 博客频道 - CSDN.NET,现