zhxiufan 发表于 2022-7-19 20:12 你这个例子举得不好,单片机的printf可以通过重定向让数据显示在屏幕上、通过串口发送、通过spi发送等等都能实现,而pc上面,printf也可以通过修改printf的实现,将数据通过串口、usb等发送出去 |
说的挺好,不过细节挺多的 |
说的都有启发啊 |
可以这样说吗,c是语言,keil是环境? |
玩单片机 得有这个单片机的规格书(原理),学习标准C的目的 是让你初步了解语法(逻辑能力),以及C语句执行后的状态,比如循环,分支,赋值;便于调试的话,需要理解一点点汇编的知识。通过看LIST文件 观看你的C语句是否被编译。有些时候你的C语句被编译后 可能不是你需要的状态 |
C语言是只是工具,选一个项目,深入了解就知道一系列东西了。 |
木示 发表于 2022-7-20 19:36 TF0为什么要清零? |
Y_G_G 发表于 2022-7-20 11:48 寄存器清零 |
木示 发表于 2022-7-20 08:53 3.2==1 这应该是P3^2,不是3.2,你的修改只是修改了错误提示而已,不代表你的代码是符合你的逻辑要求的 还有,有中断中的这个TF0=1;是什么意思? |
C语言是工具。你学会了用斧子,你是用来砍树还是用来钉钉子都可以。 |
也有人用visual C++6.0或者visual studio来写单片机程序,当比较麻烦就是了 |
移植程序,要看DATASHEET,看有哪些可用的端口,头文件要改一下, |
感谢各位大神的指导。现在编译没有问题了,不知道实际应用怎么样。这里弄错了是想使用3.2这个脚位的,void key_scan2() { if(3.2==1) 改成INT0就没有再报错了。 |
这么说吧,你学了C语言,一般的单片机 比如STM32之类的程序你能看懂功能逻辑,但是不知道为什么这么做,而如果你刚好也学习了STM32,那你就能用你的C语言结合这款硬件平台,去实现他能够实现的功能 |
C51虽然也是C语言,但与标准的C(基于X86)还是有很大区别的。库函数里面很多是同名而意不同的,比如printf函数,C51是将数据通过串口发送出去,标准C是显示在屏幕上。还有很多函数也是如此。 |
我的改动代码如下:(以上的代码皆是本论坛的坛友的,只作学习使用!) #include<reg52.h> #define uchar unsigned char// #define uint unsigned int// uint key2_time_cnt;// uchar key2_lock;//° uchar key2_num_s;// uchar key2_touch_s_flag;// uint shuzi;// uchar SYS1MS;// void PORT_init() // { PCON=0X00; TCON=0;// IE0=0;// TF0=1;// EA=1;// TH0=9;// } void key_scan2() { if(3.2==1)// { key2_lock=0;// key2_time_cnt=0;// if(key2_touch_s_flag==1)// { key2_touch_s_flag=0;// key2_num_s++;// if(key2_num_s>3)key2_num_s=0;// } } else if(key2_lock==0)// { key2_time_cnt++;// if(key2_time_cnt>149)// { key2_touch_s_flag=1;// key2_time_cnt=0;//Ç key2_lock=1;// } } } void key_service2() { switch(key2_num_s) { case 0: T1=1; T0=0; //key2_num_s=0; break; case 1: T1=0; T0=1; //key2_num_s=0; break; case 2: T1=1; T0=1; // key2_num_s=0; break; case 3: T1=0; T0=0; //key2_num_s=0; break; } } void main() { PORT_init(); while(1) { if(SYS1MS==1) { SYS1MS=0; key_scan2(); } key_service2(); } } void exint0() interrupt 0 //¶¨ê±Æ÷0ÖD¶Ïoˉêy { if((IE0&TF0)==1)// { IE0=0;// TF0=0;// TH0=9;// shuzi++; if(shuzi==4) { shuzi=0; SYS1MS=1; } TF0=1;// } } |
错误的提示如下: |
木示 发表于 2022-7-19 17:17 看错误提示! |
木示 发表于 2022-7-19 17:17 怎么可能嘛兄弟 单片机和C语言是两个知识点,两个都要学的 学习单片机最忌讳的就是把别人的一堆代码下载下来,想看一下效果,都验证点什么 单片机不是这样学的,要一步一个脚印,一点一点来的至于你想"移植",那是受了C语言简介中的"C语言可移植性好"影响 8051和PIC是两个不同指令的单片机的,端口名称都中不一样的 8051叫P0,P1........... PIC叫PA,PB............ 两者中断机制也是不一样的 8051有各个中断对应的中断入口的,中断程序只要触发了就会直接执行对应的中断 而PIC只有一个中断入口,中断触发之后要先查询中断标志位,用来判断是哪个中断,然后才执行对应的中断 8051的端口是双向的,只要释放了端口,直接就是可以读取电平也可以输出电平 而PIC在读取的时候要先把端口设定成数据输入模式才能读取到端口的电平状态 如果要输出高低电平,那就要把端口设定成数字输出模式,才能输出电平 8051只要安装了KEIL和STC下载器就可以开始学习了,可以用232下载 PIC就不一样了,你要先安装JAVA运行环境,安装MPLAB,还得安装编译器,而PIC的又有好几个编译器,每个编译器的函数都是不一样的,完还得用专用的PICKIT下载器才能下载程序 是不是对我上面的话一脸的蒙,这就对了,在你还没有真正入门之前,不要学PIC,除非有人带,或者是学校教材是这样的,又或者是工作需要 给你看一下我的第一个8051C程序,别想着一下子就能飞,你得先学会爬,然后再学会走路,走得快了,你自然就能飞了 #include<reg52.h> //包含头文件,头文件中有8051单片机的特殊寄存器地址的定义 sbit LED=P0^0; //用sbit关键字来定义LED这个端口的地址,LED方便记忆,P0这个已经在reg52.h中声明过了,可以直接P0这个名称 void main () { P0=0x00; //P0端口先低电平,因为默认上电为高电平 LED=1; //LED为高电平,LED亮或者灭要看硬件电路 while(1) //while循环为真,一直循环 { } } |
用单片机为PIC16F676,RA5上的脚作为交流检测脚。RC2,RC3作为负载输出控制端。程序如下: #include<pic.h> __CONFIG(0X1B4); #define uchar unsigned char//宏定义,相当于uchar=unsigned char #define uint unsigned int//宏定义,相当于uint=unsigned int uint key2_time_cnt;//按键去抖计数器 uchar key2_lock;//按键有效标志 uchar key2_num_s;//功能散转变量 uchar key2_touch_s_flag;//交流断电信号有效标志 uint shuzi;//时标计数变量 uchar SYS1MS;//时标开关标志 void PORT_init() { ANSEL=0X00;//普通端口设置 CMCON=0X07;//比较器关闭 TRISA=0b00110100; TRISC=0b00110000; PORTC=0X00; PORTA=0X00; T0CS=0;//定时器内部时钟选择 ; T0IF=0;//定时器中断标志清零 T0IE=1;//定时器中断使能 GIE=1;//全局中断使能 TMR0=9;//定时器初值为零 } void key_scan2() { if(RA5==1)//如果RA5上按键没有按下 { key2_lock=0;//2号键标志清零 key2_time_cnt=0;//去抖计数器清零 if(key2_touch_s_flag==1)//如果交流断电信号有效 { key2_touch_s_flag=0;//清交流信号标志 key2_num_s++;//功能号开始自加 if(key2_num_s>3)key2_num_s=0;//一共4种功能 } } else if(key2_lock==0)//如果有键第一次按下 { key2_time_cnt++;//去抖计数器开始计数 if(key2_time_cnt>149)//当计数器值大于149,说明低电平持续的时间大于10MS,而交流电高低电平的持续时间是8——10MS,这就表示交流电被断电了。 { key2_touch_s_flag=1;//交流断电有效,标志置一。 key2_time_cnt=0;//清去抖动计数器 key2_lock=1;//自锁标志置1,避免一直触发 } } } void key_service2() { switch(key2_num_s) { case 0: RC2=1; RC3=0; RA0=0; RA1=0; //key2_num_s=0; break; case 1: RC2=0; RC3=1; RA0=0; RA1=0; //key2_num_s=0; break; case 2: RC2=1; RC3=1; RA0=0; RA1=0; // key2_num_s=0; break; case 3: RC2=0; RC3=0; RA0=0; RA1=0; //key2_num_s=0; break; } } void main() { PORT_init(); while(1) { if(SYS1MS==1) { SYS1MS=0; key_scan2(); } key_service2(); } } void interrupt isr()//定时器0中断函数 { if((T0IE&T0IF)==1)//判断定时器中断 { T0IF=0;//清定时器中断标志 T0IE=0;//关定时器中断 TMR0=9;//从9加到256所用时间是250US shuzi++; if(shuzi==4) { shuzi=0; SYS1MS=1; } T0IE=1;//开定时器中断 } } 本程序对于断电检测使用了 if() { 第一区 } else if() { 第二区 } 一开始,信号高电平阶段,在第一区,要把各种标志清零,同时,要判断断电标志是否有效,这样做的目的是为了消除,交流电断电瞬间单片机会出现误动作(闪灯) ,如果作为一般按键检测的话,这里做判断,并且做出相应的按键有效处理,实际上是,等待按键松手后才做有效的处理。当有低电平到来时,实际上 else if(key2_lock==0)这语句等同于else if((!RA5)&&(!key2_lock)),RA5为低,同时按键标志没有被置1,确定上面2个条件同时成立,说明RA5端口起码是低电平了,但不一定是断电了。在第二区,然后让去抖动计数器key2_time_cnt自加,当计数器大于149时候,认为断电了(因为在一个周期内交流电低电平持续时间大概是100,所以要适当加宽低电平判断范围,)此时要马上把断电有效标志key2_touch_s_flag置1。 对于交流电断电检测功能函数key2_scan()在整个程序的位置,第一,可以直接放到定时器中断里面,每250US执行一次。第二,可以利用定时器设定一个时标比如1MS的时标,主程序中,根据时标来执行key2_scan()函数。最好不要直接放在主循环中,这样会漏掉按键检测的某个档位。 以上就是数码分段器的基本控制程序。单片机交流检测是本程序的难点。 以上是版主的代码 |
木示 发表于 2022-7-14 17:21 C语言只是一门语言而已 就是C51也只是一门语言而已 这中断,定时器是单片机方面的知识,不是语言方面的知识,所以说你要知道单片机的原理呀 手头上要有两本书,一本是单片机原理的,一本是C语言的 C语言程序设计:现代方法这本C语言的书感觉还可以,比谭老那本好多了 而8051的单片机书就多了,随便找一本就是了,没有谁比谁好多少 |
木示 发表于 2022-7-14 17:21 你这个问题就跟c语言无关了,要先学会画流程图。 |
嵌入式开发中在实际应用中,处处都会用到C语言,打印Hello Word,只是为了,看到实验现象 |
即便学了C51单片机,也只是知道(或者称之为理解)单个的程序思维。例如简单的,点亮LED灯,跑马灯这些,单个来说不难。但是如果我要把它们弄到一个程序上面来跑,比如:先亮灯,然后按下开关关闭5S内重新打开,接着跑跑马灯程序,若超过5S后开则停留在亮灯程序上来。很多新手就懵逼了,不知道怎么运用外部中断,定时器去上面跑。怎么把一些单个的程序,变成一个整体程序去跑? |
不一定会 发表于 2022-7-12 10:46 是的,差别还是大,比如说外部中断,定时器,这些在标准C语言里没有提及,但在实际应用中是十分广发的, |
51单片机使用的C语言叫C51,拥有C语言大部分的特征,并针对51单片机进行了一部分改进,以适应51单片机的硬件开发,所以叫做C51。 C51编写的源程序,是一个后缀为.c的C语言文件,编译以后的运行文件是后缀为.hex的文件。 标准C语言跟单片机的C51还是有细微差别的。 |
c语言只是一个软件语言 |
木示 发表于 2022-7-10 18:47 标准C就标准C,没有关系的 但如果你是要用在单片机方面,你要学的就是单片机原理了 |
各位的高见十分受益,感谢! 现在市面上大部分的教材,或者视频都是从标准的C语言着手,距离实际应用还是有相当的知识要学习. |
都曾有过类似问题,试着回答一下,不知是否切题。 1.首先得了解“编译器,集成开发环境(IDE)”相互联系,但不是一个东西。 2.C语言是一种高级语言,要被编译器软件编译为某一特定cpu的机器码才能运行。 VC,VS都是在pc上的集成开发环境,其内嵌编译器可编译X86处理器的win32、console等类型的应用程序。 Keil等集成开发环境在PC上运行,但使用不同的内嵌编译器,用于编译C51、ARM_M0等cpu的程序。 3.大学学的C语言,只是通用开发能力的基础,距离实际开发还有太多的内容要学,慢慢来。 4.我理解,没有“单片机的C语言”,只是用C开发产品级的单片机程序,需要对编译后的内存状态等内容了解的多一些,而且与win程序开发的常用语句有较大区别。 |
木示 发表于 2022-7-9 21:23 C和单片机C语言(比如C51)之间并没有很大的区别,如果你是工业应用,直接学单片机C语言,就可以了 这两者之间并不是说就是两种语言,无非就是增加了一些或者减少一些关键词之类 也就是说,随便学哪个C语言,只要是C语言就可以了,不同领域之间的C语言,你只要几天,或者几个小时就能上手了,不用怕"我学了标准,到时候再学单片机的话,又得学一单片机C语言?" |
主要看你在什么芯片上运行程序, 决定了用什么编译工具。 Vs编译时候根本没得选芯片 默认在PC芯片上。 keil里面可以选各种单片机。 因为这些芯片内核指令集不一样 所以不能用同一个软件去编译。 |
不是学会C语言就能开发实际产品的。 |
Y_G_G 发表于 2022-7-9 18:42 这样理解起来的话,其实除了学C语言之外,如果真的要在电子工业中应用的话,还是需要再去学单片机C语言? |
Y_G_G 发表于 2022-7-9 18:42 c语言是为了更方便的操作硬件,从而实现Unix内核而设计的,这样的结构天生就适应单片机。 |
一个是标准C语言,visual studio"Hello,the Word"是标准V语言的,实在不理解,你就当这是电脑C语言 一个是单片机C语言,keil是单片机C语言,专门为单片机准备的,C语言一开始就不是为单片机准备的 C语言我只用在单片机,其它地方没用过,也不会用 |
单片机c语言如果涉及到复杂的算法我也会在MinGW上面模拟运行,比单片机方便多了,调试通过直接移植到单片机c语言上面。 |