PIC单片机的C语言应用下的函数库
PIC C语言使用简要说明
第一部分为了对PIC单片机有更好的支持,PICC在标准C的基础上作了一些扩充:• 定义I/O函数,以便在你的硬件系统中使用中定义的函数。
• 用C语言编写中断服务程序• 用C语言编写I/O操作程序• C语言与汇编语言间的接口1-1 与标准C的不同PICC只在一处与标准C不同:函数的重入。
因为PIC单片机的寄存器及堆栈有限,所以PICC不支持可重入函数。
1-2 支持的PIC芯片PICC 支持很多PIC单片机,支持PIC单片机的类型在LIB目录下的picinfo.ini 文件中有定义。
1-3 PICC 包含一些标准库1-4 PICC 编译器可以输出一些格式的目标文件,缺省设置为输出Bytecraft的'COD' 格式和 Intel的'HEX'格式。
你可以用表1-1中的命令来指定输出格式。
表1-1格式名称描述PICC 命令文件类型Motorola HEX S1/S9 type hex file -MOT .HEXIntel HEX Intel style hex records(缺省) -INTEL .HEX Binary Simple binary image -BIN .BIN UBROF Universal Binary Image Relocatable Format -UBROF .UBR Tektronix HEX Tektronix style hex records -TEK .HEX American Hex format with symbols for American -AAHEX .HEX Automation HEX Automation emulatorsBytecraft .COD Bytecraft code format(缺省) n/a(缺省) .COD Library HI-TECH library file n/a .LIB1-5 符号文件PICC -G 命令用于生成符号文件,有了符号文件,你就可以进行源程序调试.命令格式为:PICC -16F877 -G test.c在使用仿真器时必须使用-G命令。
pic单片机C语言程序例程之wakeup
/*该程序实现PIC18F458的休眠工作方式,并由实验板上的按键产生"电平变化中断"将其从休眠状态中激活。
休眠与激活的状态由与D口相连的8个LED显示。
休眠时高4个
LED发光,低4个LED熄灭; 激活以后高4个LED熄灭,低4个LED发光*/
#include "p18f458.h"
unsigned long i;
/*系统初始化子程序*/
void initial()
{
INTCON=0x08; /*全局中断禁止,"电平变化中断"只执行唤醒功能*/
/*清除B口电平变化中断标志*/
TRISA=0x00; /*A口设置为输出*/
TRISB=0XF0; /*RB1输出,RB4输入*/
TRISD=0X00; /*D口为输出*/
TRISE=0x00; /*E口设置为输出*/
PORTBbits.RB1=0;
PORTAbits.RA3=0;
PORTE=0; /*将K1,K2,K3,K4四条列线置0*/
PORTB=PORTB; /*读PORTB的值,锁存旧值,也为“电平变化
中断”作准备*/
}
void SLEEP()
{
_asm
SLEEP /*进入休眠状态*/
_endasm
}
/*主程序*/
main ()
{
initial(); /*初始化*/
PORTD=0X0F; /*高4个LED灯亮*/
SLEEP(); /*单片机开始进入休眠状态*/
PORTD=0XF0; /*激活后,低4个LED灯亮*/
while(1)
{
;
}
}。
PIC单片机的C语言使用
PIC单片机的C语言使用PIC(Perpheral Interface Controllers)单片机是一种高性价比的嵌入式处理器,也是应用最广泛的单片机之一、它们常常用于各种电子设备,例如家电、汽车、电子仪器仪表和医疗设备等。
PIC单片机的优点是具有较低的成本、低功耗和高性能。
在C语言中使用PIC单片机可以实现许多功能,例如控制输入输出、实现逻辑运算、实现算法等。
```c#include <xc.h>#include <pic.h>void mainTRISB=0x00;//将PORTB定义为输出口PORTB=0x00;//将PORTB的值初始化为0while(1)PORTB=0xFF;//将PORTB的值设置为全高电平__delay_ms(1000); // 延时1秒PORTB=0x00;//将PORTB的值设置为全低电平__delay_ms(1000); // 延时1秒}```上述示例程序中,我们使用了XC8编译器,它是一个用于编译PIC单片机C语言程序的开源编译器。
在以上代码中,我们将PORTB定义为输出口,然后在一个无限循环中将PORTB设置为全高电平,并延时1秒,然后将PORTB设置为全低电平,并再次延时1秒。
```c#include <xc.h>#include <pic.h>void mainADCON1=0x0F;//将ADCON1寄存器设置为模拟输入模式TRISB=0x00;//将PORTB定义为输出口PORTB=0x00;//将PORTB的值初始化为0while(1)ADCON0bits.GO = 1; // 启动A/D转换while(ADCON0bits.GO); //等待转换完成//读取A/D转换结果并进行温度转换int adcValue = ADRES;int temperature = (5 * adcValue) / 1023;PORTB = temperature; // 将温度值显示在PORTB上}```在以上代码中,我们首先将ADCON1寄存器设置为模拟输入模式,然后将PORTB定义为输出口,并初始化为0。
PIC_单片机软件异步串行口实现的C语言参源程序
#i nclude <pic.h> //PIC单片机通用头文件,实际型号为16F84__CONFIG(XT | PROTECT | PWRTEN | WDTEN);//程序中设定配置信息//===========================//定义软件UART发送/接收引脚//===========================#define RX_PIN RB0 //串行接收脚#define TX_PIN RB1 //串行发送脚//===========================//定义软件UART状态机控制字//===========================#define RS_IDLE 0 //空闲#define RS_DATA_BIT 1 //数据位#define RS_STOP_BIT 2 //停止位#define RS_STOP_END 3 //停止位结束//===========================//定义软件UART采样频率//===========================#define OSC_FREQ 4000 //单片机工作频率(单位:KHz)#define BAUDRATE 1200 //通讯波特率#define TMR0PRE 2 //TMR0预分频比1:2#define TMR0CONST 117 //256 - OSC_FREQ*1000/TMR0PRE/4/(BAUDRATE*3)//===================================================================//定义函数类型void UART_Out(void);void UART_In(void);//===================================================================//定义位变量bit rsTxBusy; //串行发送忙标志//定义串行发送的数据结构struct {unsigned char state; //发送状态机控制单元unsigned char sliceCount; //波特率控制unsigned char shiftBuff; //字节数据发送移位寄存器unsigned char shiftCount; //字节数据发送移位计数器} rsTx;//定义串行接收的数据结构struct {unsigned char state; //接收状态机控制单元unsigned char sliceCount; //波特率(采样点)控制unsigned char shiftBuff; //字节数据接收移位寄存器unsigned char shiftCount; //字节数据接收移位计数器unsigned char dataBuff[8]; //接收数据FIFO缓冲队列unsigned char putPtr, getPtr;//FIFO队列存放/读取指针} rsRx;//用于串行发送的变量定义unsigned char outBuff[10]; //发送队列unsigned char outPtr, //发送队列指针outTotal, //发送的字节总数chkSum; //发送的校验码//===================================================================== //主程序//===================================================================== void main(void){PORTA = 0;PORTB = 0;TRISB = 0b01; //输入输出定义OPTION = 0b10000000; //TMR0选择内部指令周期计数//TMR0预分频 1:2rsRx.state = RS_IDLE; //初始化接收状态rsTxBusy = 0; //发送空闲INTCON = 0b00100000; //T0IE使能GIE = 1; //打开中断while(1) { //程序主循环asm("clrwdt"); //清看门狗UART_In(); //接收串行数据UART_Out(); //发送串行数据}}//=====================================================================//查询在接收FIFO队列中是否有新数据到//然后解读数据//===================================================================== void UART_In(void){unsigned char data1;if (rsRx.putPtr==rsRx.getPtr)return; //如果读取和存放的指针相同,则队列为空data1 = rsRx.dataBuff[rsRx.getPtr]; //读取1个数据字节rsRx.getPtr++; //调整读取指针到下一位置rsRx.getPtr &= 0x07; //考虑环形队列回绕//此处为数据解读分析,略}//===================================================================== //软件UART发送数据//数据在outBuff中,outTotal为总字节数//===================================================================== void UART_Out(void){if (rsTxBusy==1)return; //正处于移位发送忙//可以发送新数据if (outTotal) { //如果有字节要发送rsTx.shiftBuff = outBuff[outPtr++]; //取字节到发送移位寄存器rsTxBusy = 1; //置发送忙标志,启动发送outTotal--; //字节计数器减1}}//=================================================================== //中断服务程序//=================================================================== void interrupt isr(void){//利用TMR0 定时中断实现全双工软件UARTif (T0IE && T0IF) {T0IF = 0; //清TMR0中断标志//实现串行接收 RX 状态机控制switch (rsRx.state) { //判当前接收状态case RS_IDLE://当前状态为"空闲", 唯一要做的就是判"起始位"出现if (RX_PIN==0) { //如果接收到低电平rsRx.sliceCount = 4; //准备4*Ts时间间隔rsRx.shiftCount = 8; //总共接收8位数据位//改变此数值可以实现任意位数的数据接收rsRx.state = RS_DATA_BIT; //切换到数据位接收状态}break;case RS_DATA_BIT://当前状态为"数据接收"if (--rsRx.sliceCount==0) { //等采样时间到rsRx.shiftBuff >>= 1; //接收移位寄存器右移1位if (RX_PIN) rsRx.shiftBuff|=0x80; //保存最新收到的数据位 rsRx.sliceCount = 3; //下次采样间隔为3*Tsif (--rsRx.shiftCount==0) { //已经收到8位数据位?//保存数据字节到FIFO缓冲队列rsRx.dataBuff[rsRx.putPtr] = rsRx.shiftBuff;//队列存放指针调整,最多8个字节缓冲rsRx.putPtr = (rsRx.putPtr+1) & 0x07;//转去下个状态,判停止位rsRx.state = RS_STOP_BIT;}}break;case RS_STOP_BIT://当前状态为停止位判别(此程序没有判别)if (--rsRx.sliceCount==0) { //等采样时间到//此处可以判RX_PIN是否为1rsRx.state = RS_IDLE; //复位接收过程}break;default://异常处理rsRx.state = RS_IDLE; //复位接收过程}//实现串行发送 TX 状态机控制switch (rsTx.state) { //判当前发送状态case RS_IDLE: //发送起始位if (rsTxBusy) { //如果发送启动TX_PIN = 0; //发出起始位低电平rsTx.sliceCount = 3; //持续时间3*TsrsTx.shiftCount = 8; //数据位数为8位rsTx.state = RS_DATA_BIT; //转去下一状态} else TX_PIN = 1; //如果没有数据发送则保证数据线为空闲 break;case RS_DATA_BIT: //发送8位数据位if (--rsTx.sliceCount==0) { //码元宽度定时到if (rsTx.shiftBuff & 0x01)//看数据位是0还是1TX_PIN = 1; //发送1elseTX_PIN = 0; //发送0rsTx.shiftBuff >>= 1; //准备下次数据位发送rsTx.sliceCount = 3; //数据位宽度为3*Tsif (--rsTx.shiftCount==0) {//8位数据位发送结束,转去发送停止位rsTx.state = RS_STOP_BIT;}}break;case RS_STOP_BIT: //发送1位停止位if (--rsTx.sliceCount==0) { //等数据位发送结束TX_PIN = 1; //发送停止位高电平rsTx.sliceCount = 9; //持续宽度9*Ts//额外考虑字节连续发送的时间间隔rsTx.state = RS_STOP_END; //转停止位宽度延时}break;case RS_STOP_END: //等待停止位时间宽度结束if (--rsTx.sliceCount==0) { //如果停止位结束时间到rsTxBusy = 0; //一个字节发送过程结束,清发送忙标志rsTx.state = RS_IDLE; //复位发送过程}break;default://异常处理rsTx.state = RS_IDLE; //复位发送过程}TMR0 += TMR0CONST; //重载TMR0,实现下次定时中断}}。
pic单片机C语言程序例程之stopwatch
//此程序实现计时秒表功能,时钟显示范围00.00~99.99秒,分辨度:0.01秒#include "p18f458.h"unsigned char s[4]; //定义0.01 秒、0.1 秒、1秒、10秒计时器unsigned char k,data,sreg;unsigned int i;const table[11]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0XD8,0x80,0x90};//不带小数点的显示段码表const table0[10]={0X40,0X79,0X24,0X30,0X19,0X12,0X02,0X78,0X00,0X10};//带小数点的显示段码表void clkint(void);//TMR0初始化子程序void tmint(){T0CON=0XCF; //设定TMR0L工作于8位定时器方式//内部时钟,TMR0不用分频INTCON=0X20; //总中断禁止,TMR0中断允许,清除TMR0的中断标志INTCON2bits.TMR0IP=1; //TMR0中断高优先级RCONbits.IPEN=1; //使能中断优先级}//系统其它部分初始化子程序void initial(){TRISA=0x00; //A口设置为输出TRISB=0XF0; //RB1输出,RB4输入TRISC=0x00; //SDO引脚为输出,SCK引脚为输出TRISE=0x00; //E口设置为输出SSPCON1=0x30; //SSPEN=1;CKP=1,FOSC/4SSPSTA T=0xC0; //时钟下降沿发送数据PIR1=0; //清除SSPIF标志data=0X00; //待显示的寄存器赋初值PORTBbits.RB1=0;PORTAbits.RA3=0;PORTE=0; //将K1,K2,K3,K4四条列线置0//SPI传输数据子程序void SPILED(char data){SSPBUF=data; //启动发送do{;}while(PIR1bits.SSPIF==0);PIR1bits.SSPIF=0;}//显示子程序,显示4位数void dispaly(){PORTAbits.RA5=0; //准备锁存for(k=0;k<4;k++){data=s[k];if(k==2) data=table0[data]; //个位需要显示小数点else data=table[data];SPILED(data); //发送显示段码}for(k=0;k<4;k++){data=0xFF;SPILED(data); //连续发送4个DARK,使显示好看一些}PORTAbits.RA5=1; //最后给锁存信号,代表显示任务完成}//软件延时子程序void DELA Y(){for(i = 3553; --i ;)continue;}//键扫描子程序void KEYSCAN(){while(1){dispaly(); //调用一次显示子程序while(PORTBbits.RB4==0){DELA Y(); //若有键按下,则软件延时break;}if (PORTBbits.RB4==0) break; //若还有键按下,则终止循环扫描,返回}}//等键松开子程序void keyrelax(){while(1){dispaly(); //调用一次显示子程序if (PORTBbits.RB4==1) break; //为防止按键过于灵敏,每次等键松开才返回}}/*高优先级中断向量*/#pragma code InterruptV ectorHigh=0x08void InterruptV ectorHigh (void){_asmgoto clkint //跳到中断程序_endasm}//中断服务程序#pragma code#pragma interrupt clkintvoid clkint(){TMR0=0X13; //对TMR0写入一个调整值。
PIC单片机C语言程序设计_10_
表6
Pic07.c 的语句或函数名称,
模拟运行 fima
从 Void main( )后开始
(耗时)
TRISA=Ox10 ;
2μs
PORTB= Ox40 ;
3μs
INTCON= Ox00 ;
2μs
X=0 ;
2μs
While (RA4)
2μs
Displag(x) →调用显示函数体 2μs
Unsighid int d=100……
⑷ Step Into、step over 和 Step out 命令配 合运行调试
前面讲到,用 Animate(动画运行)命令,观 察 pic07.c 程序运行,会感到运行速度较快,看不 清楚程序经过的路径。这里介绍用工具栏快捷图标 (见图 43)中的命令 Step Into、Step over 和 Step out,对程序进行模拟调试的方法,其功能见表 5。
作者 丁锦滔
就业技能
JOBSEEKERS
PIC单片机C语言程序设计(10)
(接上期)
4. C程序pic07.c的SIM软件仿真调试 在《PIC 单片机 C 语言程序设计(8)》和《PIC 单片机 C 语言程序设计(9)》中,我们已对 C 程 序 pic07.c 进行了编辑和编译,现在需要查看该程 序能否达到预期的设计目标,即能否完成 pic07.c 的 0~99 秒增量计时 LED 数码显示功能(脉冲发生 器),因此需要调试程序。 调试程序,可以使用 MPLAB ICD2 在线调试器、 MPLAB ICE2000 硬件仿真器等开发工具。对于初 学 C 语言程序,又没有上述硬件仿真调试器的读者, 最好选用 MPLAB SIM 软件模拟仿真器进行程序的 调试。 模拟仿真调试是检查程序是否正确,能否实现 预期功能的有效手段。有了它,可以实现程序的“单 步运行”、“单步越过”、设置“断点”、用软件跑表 直接测试延时函数的准确计时等等,对初学 C 语言 编程者特别有用。 PTC 单片机的 C 语言程序,是由函数、表达式 和各种运算符组成的。初学 C 语言程序时,很难清 楚看出程序是如何运行的,而利用程序的模拟仿真, 则可直观看到程序运行的整个过程。 ⑴ 模拟仿真的主要命令及功能 PIC 单片机 C 语言程序的 SIM 软件的模拟仿真, 是在 MPLAB IDE 集成开发环境(C 语言)中进行 的。操作时,只需利用 MPLAB IDE 中的有关菜单, 如 Debugger(调试)、Select Tool 等命令项,即可 完成模拟仿真操作。为了方便读者查看程序或操作, 特将模拟仿真时常用的主要命令和功能汇集起来, 如表 5 所示。 ⑵ 设置软件仿真调试状态窗口 前面已经讲到,对程序进行软件仿真的先决条 件,是在 MPLAB IDE 环境下将所编辑的源程序编 译成功后,才能对源程序进行仿真调试。对 pic07.
PIC C语言编程
下例中,是将整数0X80的低2位置为1。
|)
10000000 00000011 —————— 10000011
(5)按位异或
01111111 ^) 01111000 —————— 00000111
7 条件运算符
条件运算符(?:)能用来代替某些if—then— else形式的语句。 一般形式为: EXP1 ? EXP2 : EXP3
9 增1和减 运算符 和减1运算符 和减
(前缀)++操作数 或 --操作数 (后缀)操作数++ 或 操作数—
x=++n; //n先加1,再赋给x。 结果是n=6,x=6 x=n++; //先把n值赋给x,n值在加1。 结果是n=6,x=5;
10 取地址运算符 取地址运算符“&”和取内容运算符 和取内容运算符“*” 和取内容运算符 “&”运算符用于取出操作数的地址,“*”运算符 是通过指针间接的访问一个值,在指针类型中 应用很多。
PIC单片机C语言编程
2011.3
内容
C语言编译器 C语言编程
C语言编译软件
PICC Microchip公司的第三方公司HITECH公司 编写的C语言编译器。 MAPLAB C18 Microchip公司编写的C语言编译器。
MAPLAB C18
1 建立项目
选择Project>New 来创建一个新项目。然后在所显示的对话框 中输入项目名及其路径,再点击OK。
下图所示的“General”选项卡中输入MPLAB C18 安装目录中 头文件和函数库子目录的路径。可以直接输入路径或点击 Browse 指定路径。MPLAB C18 会在指定的头文件目录下搜 索包含的.h 文件。MPLINK 链接器会在函数库目录下搜索目 标文件和库文件,其中包括在链接描述文件中指定的文件。
单片机C语言C的常用库函数
C51的常用库函数详解C51语言的编译器中包含有丰富的库函数,使用库函数可以大大简化用户程序设计的工作量,提高编程效率;每个库函数都在相应的头文件中给出了函数原型声明,在使用时,必须在源程序的开始处使用预处理命令include将有关的头文件包含进来;C51库函数中类型的选择考虑到了8051单片机的结构特性,用户在自己的应用程序中应尽可能地使用最小的数据类型,以最大限度地发挥8051单片机的性能,同时可减少应用程序的代码长度;下面将C51的库函数分类列出并详细介绍其用法;1字符函数字符函数的原型声明包含在头文件CTYPE.H中;常用的一些字符函数介绍如下;1.1检查英文字母函数检查英文字母函数用于检查形参字符是否为英文字母,其函数原型如下:bitisalphacharc;其中,c为待判断的字符,如果是英文字母则返回1,否则返回0;程序示例如下:1.2检查字母数字函数检查字母数字函数用于检查形参字符是否为英文字母或数字字符,其函数原型如下:bitisalnumcharc;1.3检查控制字符函数检查控制字符函数用于检查形参字符是否为控制字符,其函数原型:bitiscntrlcharc;其中,c为待判断的字符;控制字符其取值范围为0x00~0xlF之间或等于0x7F,如果是,则返回1,否则返回0;十进制数字检查函数用于检查形参字符是否为十进制数字,其函数原型如下:bitisdigitcharc;其中,c为待判断的字符,如果是十进制数字则返回1,否则返回0;1.5可打印字符检查函数可打印字符检查函数用于检查形参字符是否为可打印字符,其函数原型如下:bitisgraphcharc;其中,c为待判断的字符;可打印字符的取值范围为0x21~0x7C,不包含空格,如果是可打印字符则返回1,否则返回0;1.6包含空格的可打印字符检查函数包含空格的可打印字符检查函数用于检查形参字符是否为可打印字符以及空格,其函数原型如下:bitisprintcharc;其中,c为待判断字符;如果是则返回1,否则返回0;该函数与isgraph的区别在于包含了空格符,空格符为0x20;1.7格式字符检查函数格式字符检查函数用于检查形参字符是否为标点、空格或格式字符,其函数原型如下:bitispunctcharc;其中,c为待判断字符,如果是则返回1,否则返回0;1.8小写英文字母检查函数小写英文字母检查函数用于检查形参字符是否为小写英文字母,其函数原型如下:bitislowercharc;1.9大写英文字母检查函数大写英文字母检查函数用于检查形参字符是否为大写英文字母,其函数原型如下:bitisuppercharc;其中,c为待判断字符;如果是大写英文字母则返回1,否则返回0;1.10控制字符检查函数控制字符检查函数用于检查形参字符是否为控制字符,其函数原型如下:bitisspacecharc;其中,c为待判断字符;如果是控制字符则返回1,否则返回0;控制字符包括:空格、制表符、回车、换行、垂直制表符和送纸,其取值范围为0x09~0x0d,或为0x20;1.11十六进制数字检查函数十六进制数字检查函数用于检查形参字符是否为十六进制数字,其函数原型如下:bitisxdigitcharc;其中,c为待判断字符;如果是16进制数字字符则返回1,否则返回0;1.12十六进制数字转换函数十六进制数字检查函数用于转换形参字符为十六进制数字,其函数原型如下:chartointcharc;其中,c为待转换字符;该函数将形参字符0~9、a~f大小写无关转换为16进制数字;其中,对于字符0~9,返回值为0H~9H,对于ASCII字符a~f大小写无关,返回值为0AH~0FH;1.13大写字符转换函数chartolowercharc;其中,c为待转换的大写字符;如果字符参数不在A~Z之间,则该函数将不起作用,而直接返回原字符;1.14小写字符转换函数小写字符转换函数用于将小写字符转换为大写字符,其函数原型如下:chartouppercharc;其中,c为待转换的小写字符;如果字符参数不在a~z之间,则该函数将不起作用,而直接返回原字符;1.15ASCII字符转换函数ASCII字符转换函数用于将任何字符型参数缩小到有效的ASCII范围之内,其函数原型如下:chartoasciicharc;其中,c为待转换的字符;该函数执行的操作是将形参数值和0x7f做与运算,从而去掉第7位以上的所有位数;如果形参已是有效的ASCII字符,则不作处理,直接返回原字符;1.16大写字符宏转换函数大写字符宏转换函数用于大写字符转换为小写字符,其函数原型如下:char_tolowercharc;其中,c为待转换的大写字符;这其实是一个由宏定义完成的操作,其功能是将字符参数c与常数0x20逐位进行或运算,从而将大写字符转换为小写字符;1.17小写字符宏转换函数小写字符宏转换函数用于小写字符转换为大写字符,其函数原型如下:char_touppercharc;其中,c为待转换的小写字符;这其实是一个由宏定义完成的操作,其功能是将字符参数c与常数0xdf逐位进行与运算,从而将小写字符转换为大写字符;2字符串函数字符串函数的原型声明包含在头文件STRING.H中;在C51语言中,字符串应包括2个或多个字符,字符串的结尾以空字符来表示;字符串函数通过接受指针串来对字符串进行处理;常用的字符串函数介绍如下;2.1字符查找函数字符查找函数用于在字符串中顺序查找字符,其函数原型如下:voidmemchrvoidsl,charval,intlen;其中,s1为输入字符串,val为待查找的字符,len为查找的长度范围;该函数的功能是在字符串s1中顺序搜索前len个字符以找出字符val,如果找到则返回sl中指向val的指针,如果没有找到则返回NULL;2.2指定长度的字符串比较函数指定长度的字符串比较函数用于按照指定的长度比较两个字符串的大小,其函数原型如下:charmemcmpvoids1,voids2,intlen;其中,s1和s2为输入字符串,len为比较的长度;该函数的功能是逐个比较字符串sl和s2的前len个字符,如果相等则返回0,如果字符串s1大于s2,则返回一个正数,如果字符串s1小于s2,则返回一个负数;如果两个字符串的长度小于len,该函数仍将一直比较len个字符,这种情况下,有可能结果是错误的;因此应该保证len不能超过最短字符串的长度;2.3字符串复制函数字符串复制函数用于复制指定长度的字符串,其函数原型如下:其中,dest为目标字符串,src为源字符串,len为复制的长度;该函数的功能是从src所指向的字符串中复制len个字符到dest字符串中,其返回值指向dest中的最后一个字符的指针;2.4带终止字符的字符串复制函数带终止字符的字符串复制函数用于复制字符串,如果遇到终止字符则停止复制,其函数原型如下:voidmemccpyvoiddest,voidsrc,charval,intlen;其中,dest为目标字符串,src为源字符串,val为终止字符,len为复制的长度;该函数的功能是复制字符串src中的len个字符到dest中,复制len个字符后则返回NULL;如果遇到字符val则停止复制,此时返回一个指向dest中的下一个元素的指针;2.5字符串移动函数字符串移动函数同样用于复制字符串,其函数原型如下:voidmemmovevoiddest,voidsrc,intlen;其中,dest为目标字符串,src为源字符串,len为复制长度;该函数的功能是从src所指向的字符串中复制len个字符到dest字符串中,其返回值指向dest中的最后一个字符的指针;其功能与memcpy相同,但是复制区间src与dest可以发生交迭;2.6字符串填充函数字符串填充函数用于按规定的字符填充字符串,其函数原型如下:voidmemsetvoids,charval,intlen;其中,s为待填充的字符串,val为填充字符,len为填充的长度;该函数实现的操作是用字符val来填充字符串s,共填充len个单元2.7字符串追加函数voidstrcatchars1,chars2;其中,s1为目标字符串,s2为待复制的字符串;该函数实现的操作是将字符串s2复制到字符串s1的尾部;其中字符串s1要有足够的大小来保存两个字符串;该函数的返回值指向字符串s1中的第一个字符的指针;2.8指定长度的字符串追加函数指定长度的字符串追加函数用于复制指定长度的字符串到另一个字符串的尾部,其函数原型如下:voidstrncat,chars1,chars2,intn;其中,s1为目标字符串,s2为待复制的字符串,n为复制的长度;该函数实现的操作是从字符串s2中复制n个字符添加到字符串s1的尾部;其中,如果字符串s2的长度比n小,则将全部复制字符串s2包括串结束符;2.9字符串比较函数字符串比较函数用于比较两个字符串的大小,其函数原型如下:charstrcmpchars1,chars2;其中,s1和s2为待比较的字符串;该函数的功能是比较字符串s1和s2,如果两者相等则返回0;如果s1<s2,则返回一个负数;如果s1>s2,则返回一个正数;2.10包含结束符的字符串比较函数包含结束符的字符串比较函数用于比较两个字符串的大小,其函数原型如下:charstrncmpchars1,chars2,intn;其中,s1和s2为待比较的字符串,n为比较的长度;该函数的功能是比较字符串s1和s2的前n个字符,如果两者相等则返回0;如果s1<s2,则返回一个负数;如果s1>s2,则返回一个正数;这里需要和memcmp函数相区别,如果字符串的长度小于n,则strncmp函数比较到字符串结束符后便停止,这和memcmp函数是不一样的;字符串覆盖函数用于将一个字符串覆盖另一个字符串,其函数原型如下:charstrcpychars1,chars2;其中,s1为目标字符串,s2为源字符串;该函数的功能是将字符串s2包括结束符复制到字符串s1中的第1个字符指针处;这里需要注意和strcat函数相区别,strcat 函数将字符串s2复制到字符串s1的末尾;2.12指定长度的字符串覆盖函数指定长度的字符串覆盖函数用于将一个指定长度的字符串覆盖另一个字符串,其函数原型如下:charstrncpychars1,chars2,intn;其中,s1为目标字符串,s2为源字符串,n为长度;该函数实现的操作是从字符串s2包括结束符中复制n个字符到字符串s1中的第1个字符指针处;如果字符串s2的长度小于n,则s1串以0补齐到长度n;2.13获取字符串个数函数获取字符串个数函数用于返回字符串中字符总数,其函数原型如下:charstrlenchars1;其中,s1为输入字符串;该函数的功能是获取字符串s1中的字符个数,返回值的大小不包括结尾的字符串结束符;2.14搜索字符串函数搜索字符串函数用于搜索字符串出现的位置,其函数原型如下:charstrstrconstchars1,chars2;其中,s1为目标字符串,s2为搜索的字符串;该函数实现的操作是在字符串s1中搜索第一次出现字符串s2的位置,并返回该处的指针;如果字符串s1中不包括字符串s2,则该函数返回一个空指针;搜索字符函数用于搜索字符出现的位置,其函数原型如下:charstrchrchars1,charc;其中,s1为目标字符串,c为待搜索的字符;该函数的功能是搜索字符串s1中是否包含字符c,如果包含则返回第一次指向该字符的指针,否则返回NULL;被搜索的字符可以是串结束符,此时返回值是指向串结束符的指针;2.16返回位置值的字符搜索函数返回位置值的字符搜索函数用于搜索并返回字符出现的位置,其函数原型如下:intstrposchars1,charc;其中,s1为目标字符串,c为搜索的字符;该函数的功能是查找并返回字符c在字符串s1中第一次出现的位置值,没有找到该字符则返回-1,s1串首字符的位置值是0;strpos函数的功能与strchr类似,只不过返回值不同;2.17字符包含函数字符包含函数用于检查字符串中是否包含某字符,其函数原型如下:charstrrchrchars1,charc;其中,s1为目标字符串,c为查找的字符;该函数的功能是搜索字符串s1中是否包含字符c,如果包含则返回最后一次指向该字符的指针,否则返回NULL;被搜索的字符可以是串结束符,此时返回值是指向串结束符的指针;2.18返回位置值的字符包含函数返回位置值的字符包含函数同样用于检查字符串中是否包含某字符,其函数原型如下:intstrrposchars1,charc;其中,s1为目标字符串,c为查找的字符;该函数的功能是查找并返回字符c在字符串s1中最后一次出现的位置值,没有找到该字符则返回-1,s1串首字符的位置值是2.19在指定字符集中查找不包含字符函数在指定字符集中查找不包含字符函数用于查找不包含在指定字符集中的字符,其函数原型如下:intstrspnchars1,charset;其中,s1为目标字符串,set为字符集;该函数的功能是搜索字符串s1中第一个不包含在set串中的字符,返回值是字符串s1中包括在set中的字符的个数;如果s1中所有的字符都包含在set中,则返回s1的长度不包括结束符;如果set是空字符串则返回0;2.20在指定字符集中查找包含字符函数在指定字符集中查找包含字符函数用于查找包含在指定字符集中的字符,其函数原型如下:intstrcspnchars1,charset;其中,s1为目标字符串,set为字符集;该函数的功能是搜索的是第一个包含在set串中字符,返回值是字符串s1中包括在set中的字符的个数;如果s1中所有的字符都包含在set中,则返回s1的长度不包括结束符;如果set是空字符串则返回0;2.21查找第一个包含字符函数查找第一个包含字符函数用于查找第一个包含在指定字符集中的字符,其函数原型如下:charstrpbrkchars1,charset;其中,s1为目标字符串,set为字符集;该函数的功能是搜索字符串s1中第一个包含在set串中的字符,返回值指向搜索到的字符的指针,如果未找到,则返回NULL;2.22查找最后一个包含字符函数查找最后一个包含字符函数用于查找最后一个包含在指定字符集中的字符,其函charstrrpbrkchars1,charset;其中,s1为目标字符串,set为字符集;该函数的功能是搜索字符串s1中最后一个包含在set串中的字符,返回值指向搜索到的字符的指针,如果未找到,则返回NULL; 3I/O函数I/O函数主要用于数据的输入输出等操作,C51的I/O库函数的原型声明包含在头文件STDIO.H中;这些I/O函数使用8051单片机的串行接口进行通信,因此,在使用之前需要先进行串口的初始化;例如:SCON=0x50; //串口模式1,允许接收TMOD|=0x20; //初始化T1为定时功能,模式2PCON|=0x80; //设置SMOD=1TL1=0xF4; //波特率4800bit/s,初值TH1=0xF4;IE|=0x90; //中断TR1=1; //启动定时器3.1字符读入函数字符读入函数用于从串口读入一个字符,其函数原型如下:char_getkeyvoid;该函数执行的操作是等待从8051的串口读入一个字符,并返回读入的原字符;程序示例如下:3.2字符读入输出函数字符读入输出函数用于从串口读入一个字符并输出该字符,其函数原型如下:chargetcharvoid;该函数与_getkey函数有细微的不同,其执行的操作是使用_getkey从串口读入的一个字符,然后使用putchar函数将读入的字符输出;3.3字符串读入函数字符串读入函数用于从串口读入一个字符串,其函数原型如下:chargetschars,intn;其中,s保存读入的字符串,n为字符串的长度;该函数执行的操作是使用getchar 函数从串口读入一个长度为n的字符串,并存入字符数组s中;如果遇到换行符,则结束字符的输入;输入成功时将返回传入的参数指针,失败时返回空指针NULL;3.4字符回送函数字符回送函数用于将输入的字符回送到输入缓冲区,其函数原型如下:charungetcharcharc;其中,c为输入字符;该函数执行的操作是将输入的字符回送到输入缓冲区,如果函数调用成功则返回char型值c,失败时则返回EOF;3.5字符输出函数字符输出函数用于通过8051串行口输出字符,其函数原型如下:charputcharcharc;其中,c为通过8051串行口输出的字符;3.6格式化输出函数格式化输出函数用于按照一定的格式输出数据或字符串,其函数原型如下:intprintfconstcharfmstr,argument…;该函数的功能是以一定的格式通过8051单片机的串行口输出数值和字符串;其中第一个参数fmstr是格式控制字符串,参数argument可以是字符串指针、字符或数值,该函数的返回值为实际输出的字符个数;3.7格式化内存缓冲区输出函数格式化内存缓冲区输出函数用于按照一定的格式将数据或字符串输出到内存缓冲区中,其函数原型如下:intsprintfchars,constcharfmstr,argument…;该函数执行的操作是通过指针s,将字符串送入内存数据缓冲区,并以ASCII码的形式储存;3.8字符串输出函数字符串输出函数用于将字符串和换行符写入串行口,其函数原型如下:intputsconstchars;其中,s为输出的字符串或换行符;如果执行成功则返回0,错误时返回EOF;程序示例如下:3.9格式化输入函数格式化输入函数用于将字符串和数据按照一定的格式从串口读入,其函数原型如下:intscanfconstcharfmstr,argument…;该函数的功能是在格式字符的控制下从串行口读入数据;其中每个参数都必须是指针;scanf返回值是所发现并转换的输入项数,如遇到错误则返回EOF;该函数的格式控制字符串形式如下,方括号内是可选项;%width{Bhl}type3.10格式化内存缓冲区输入函数格式化内存缓冲区输入函数用于将格式化的字符串和数据送入数据缓冲区,其函数原型如下:intsscanfchars,constcharfmstr,argument…;该函数的功能是将输入的字符串通过指针s指向的数据缓冲区;输入数据根据格式控制字符串fmstr被存放到由argument指定的地址;其它方面,sscanf函数与scanf函数类似;3.11字符串内存输出函数字符串内存输出函数用于将格式化字符串输出到内存数据缓冲区,其函数原型如下:intvprintfconstcharfmstr,charargptr;其中,fmstr为格式化字符串,argptr指向变量表的指针而不是变量表,函数返回值为实际写入到输出字符串中的字符数;其它方面,vprintf函数与printf函数类似;3.12指向缓冲区的输出函数指向缓冲区的输出函数用于将格式化字符串和数字输出到由指针所指向的内存数据缓冲区,其函数原型如下:intvsprintfchars,constcharfmstr,charargptr;该函数执行的操作是将格式化字符串和数字输出到由指针所指向的内存数据缓冲区;其中,该函数接受的是一个指向变量表的指针而不是变量表,其返回值为实际写入到输出字符串中的字符数;其他方面vsprintf函数与sprintf函数类似;4数学函数数学函数主要用于进行数学运算,其原型声明包含在头文件MATH.H中;下面介绍一些常用的数学函数;4.1绝对值函数绝对值函数用于计算并返回输出数据的绝对值;按照其操作数的数据类型的不同,有如下几种形式:intabsintval;charcabscharval;floatfabsfloatval;longlabslongval这些函数分别用于计算整型、字符型、浮点型以及长整型数据的绝对值;4.2指数以及对数函数指数函数用于计算并返回输出数据的指数;对数函数用于计算并返回输出数据的对数;其函数原型示例如下:floatexpfloatx;floatlogfloatx;floatlog10floatx;floatsqrtfloatx;其中exp函数用于计算并返回浮点数x的指数,log函数用于计算并返回浮点数x 的自然对数自然对数以e为底,e=2.718282,log10函数用于计算并返回浮点数x的以10为底的对数值,sqrt函数用于计算并返回浮点数x的平方根;4.3三角函数三角函数用于计算数学中三角函数的值;在C51语言中包含如下几种三角函数:floatcosfloatx;floatsinfloatx;floattanfloatx;floatacosfloatx;floatasinfloatx;floatatanfloatx;floatatan2floaty,floatx;floatcoshfloatx;floatsinhfloatx;floattanhfloatx;4.4取整函数取整函数用于取输入数据的整数;在C51语言中,包含两类取整函数,示例如下:floatceilfloatx;floatfloorfloatx;其中ceil函数用于计算并返回一个不小于x的最小正整数作为浮点数,floor函数用于计算并返回一个不大于x的最小正整数作为浮点数;4.5浮点型分离函数浮点型分离函数用于将浮点型数据的整数和小数部分分开,其函数原型如下:floatmodffloatx,floatip;函数modf将浮点数x分成整数和小数两部分,整数部分放入ip,返回值为小数部分;两者都含有与x相同的符号;4.6幂函数幂函数用于进行幂指数运算;其函数原型如下:floatpowfloatx,floaty;该函数用于计算并返回xy的值;如果x不等于0而y=0,则返回1;当x=0且y<=0或x<0且y不是整数时,返回NaN;5标准函数标准函数主要用于完成数据类型转换以及存储器分配等操作;标准函数的原型声明包含在头文件STDLIB.H中;下面介绍常用的一些函数;5.1字符串转换函数字符串转换函数用于将字符串转换成数值类型并输出;根据输出数值类型的不同,可以有如下几种形式:floatatoicharsl;floatatolcharsl;floatatofcharsl;其中,atoi函数用于将字符串sl转换成整型数值并返回该值;输入字符串的格式为:whitespace{+/-}数字;其中,whitespace可由空格、/、制表符组成;这里的数字可以是一个或多个十进制数;5.2带返回指针的字符串转换函带返回指针的字符串转换函数将字符串转换成数值类型并输出,同时返回未转换部分的指针;根据输出数值类型的不同,可以有如下几种形式:floatstrtodconstchars,charptr;longstrtolconstchars,charptr,unsignedcharbase;unsignerlongstrtoulconstchars,charptr,unsignedcharbase;5.3随机函数随机函数用于产生伪随机数;在C51语言中,包含两种随机函数,其函数声明如下:intrand;voidsrandintn;其中,函数rand用于返回一个0到32767之间的伪随机数,而函数srand用来初始化随机数发生器的随机种子;如果不使用srand函数,则对rand函数的相继调用将产生相同的随机序列;5.4数组内存分配函数数组内存分配函数用于为n个元素的数组分配内存空间,其函数原型如下:voidcallocunsighedintn,unsighedintsize;其中n数组元素的个数,size为数组中每个元素的大小;该函数所分配的内存区域用0进行初始化;返回值为已分配的内存单元起始地址,如果不成功则返回0; 5.5释放内存函数释放内存函数用于释放前面已分配的内存空间,其函数原型如下:voidfreevoidxdatap;其中,指针p指向待释放的存储区域;p必须是以前用calloc、malloc或realloc 函数分配的存储区域,如果p为NULL,则该函数无效;经free函数所被释放的存储区域可以参与以后的分配;5.6初始化内存函数初始化内存函数用于对前面申请的内存进行初始化,其函数原型如下:voidinit_mempoolvoidxdatap,unsighedintsize;其中,指针p表示存储区首地址,size表示存储区大小;该函数可对被函数calloc、malloc、free或realloc管理的存储区域进行初始化;5.7内存分配函数内存分配函数用于在内存中分配指定大小的存储空间,其函数原型如下:voidmallocunsighedintsize;其中,size为分配的空间大小,返回值为指向所分配内存的指针;如果返回NULL,则表示没有足够的内存空间可用;5.8调整内存大小函数调整内存大小函数用于调整先前分配的存储器区域大小,其函数原型如下:voidreallocvoidxdatap,unsighedintsize;其中,参数p表示该存储区域的起始地址,参数size表示新分配的存储区域大小;该函数的返回值为新区域所指向的指针;如果返回NULL,则表示没有足够的内存空间可用;原存储器区域的内容被复制到新存储器区域中,如果新存储器区域较大,多出的区域不作初始化;6内部函数内部函数的原型声明包含在头文件INTRINS.H中;下面介绍常用的一些函数; 6.1循环左移函数循环左移函数主要用于将数据按照二进制循环左移n位;按照操作数据类型的不同,其函数原型如下几种形式:unsighedchar _crol_unsighedcharval,unsighedcharn;unsighedint _irol_unsighedintval,unsighedcharn;unsighedlong _lrol_unsighedlongval,unsighedcharn;其中,val为待移位的变量,n为循环移位的次数;函数_crol_、_irol_和_lrol_分别用于字符型、整型和长整形变量的循环左移,其返回值分别为移位后的字符型、整型和长整形;该函数与8051单片机的RLA指令相关;6.2循环右移函数循环右移函数主要用于将数据按照二进制循环右移n位;按照操作数据类型的不同,其函数原型如下几种形式:unsighedchar _cror_unsighedcharval,unsighedcharn;unsighedint _iror_unsighedintval,unsighedcharn;unsighedlong _lror_unsighedlongval,unsighedcharn;其中,val为待移位的变量,n为循环移位的次数;函数_cror_、_iror_和_lror_分别用于字符型、整型和长整形变量的循环右移,其返回值分别为移位后的字符型、整型和长整形;该函数与8051单片机的RRA指令相关;6.3延时函数延时函数用于使单片机程序产生延时,其函数原型如下:void_nop_void;该函数类似于8051单片机的NOP指令;程序示例如下:include<intrins.h> //头文件include<reg51.h>void mainvoid //主函数。
[工学]PIC单片机C语言编程集锦
设为首页加入收藏联系我们减小字体增大字体5.2.3 程序清单下面给出已经在实验板上调试通过的一个程序,可作为用户编制其它程序的参考。
#include <pic1687x.h>/*该程序用于在8个LED上依次显示1~8等8个字符*/static volatile int table[20]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0XD8,0x80,0x90,0x88,0x83, 0xc6,0xa1,0x86,0x8e,0x7f,0xbf,0x89,0xff};volatile unsigned char data;#define PORTAIT(adr,bit) ((unsigned)(&adr)*8+(bit)) /*绝对寻址位操作指令*/static bit PORTA_5 @ PORTAIT(PORTA,5);/*spi初始化子程序*/void SPIINIT(){PIR1=0;SSPCON=0x30; /* SSPEN=1;CKP=0 , FOSC/4 */SSPSTAT=0xC0;TRISC=0x00; /*SDO引脚为输出,SCK引脚为输出*/}/*系统各输入输出口初始化子程序*/void initial(){TRISA=0x00; /*A口设置为输出*/INTCON=0x00; /*关闭所有中断*/PORTA_5=0; /*LACK送低电平,为锁存做准备*/}/*SPI发送子程序*/void SPILED(int data){SSPBUF=data; /*启动发送*/do{;}while(SSPIF==0); /*等待发送完毕*/SSPIF=0; /*清除SSPIF标志*/}/*主程序*/main()unsigned I;initial(); /*系统初始化*/SPIINIT() ; /*SPI初始化*/for(i=8;i>0;i--) /*连续发送8个数据*/{data=table[i]; /*通过数组的转换获得待显示的段码*/SPILED(data); /*发送显示段码显示*/}PORTA_5=1; /*最后给锁存信号,代表显示任务完成*/}5.3.3 程序清单下面给出已经在实验板上调试通过的程序,可作为用户编制其它程序的参考。
PIC 单片机 C 语言程序
电子报/2007年/7月/15日/第015版单片机应用PIC单片机C语言程序——实例2成都立本在上一讲中,笔者对PIC单片机C语言程序作了定性介绍,其目的是使读者对C语言有所了解。
至于C语言的语法规则、程序设计方法、C编译器等内容,笔者将通过更多的C程序实例逐一介绍。
二、C语言的标识符和关键字1.C语言的标识符在C语言中所用到的文件名、函数名、变量名、数组名……,都是由字符组成的。
字符由英语字母和下划线组成,字符的组合称为C语言的标识符。
标识符是由C程序设计者自定义的。
标识符的第一个字符通常是字母,其后可以是字母或下划线,下划线可作为标识符的分段。
不同的C编译器对标识符的长度有不同的要求,在编程时定义的标识符不得超过所用编译器规定的长度,以免编译时出现错误。
在本文中,笔者介绍的C语言程序自定义的标识符不超过一个字节,在各种编译器的规范以内。
上一讲的C程序实例1中,delay、main均为C语言的标识符。
注意:同一字母的大小写,被视为不同的标识符,在设计C程序中不能混合使用。
2.C语言的关键字C语言中的关键字(又称为保留字)是C系统定义了的特定标识符,用户自定义的C标识符不能与这些关键字的字符相同,否则编译不会成功。
C语言中的关键字可分成三类:1)数据类关键字;2)程序控制类关键字;3)预处理类关键字。
C语言的主要关键字如表1所示。
三、实例2:PIC16F877的D 口(PORTD )位操作功能 C 语言程序中关键字十分重要。
为使读者有较多的感性认识,笔者通过实例2,用C 语言(包含更多的关键字)编写PIC 单片机任一口的位操作功能程序(实际上,在上一讲中,是用C 语言编写PIC 单片机任一口的字节操作功能)。
图2的示意电路是使PIC16F877(用PIC16F84A的B口同样有效)的D口,即RD0~RD3,外接的LED顺序(以秒为单位)循环点亮。
如果读者有兴趣,可在以下的C程序中添加RD4~RD7外接LED的点亮功能。
PIC单片机的C语言
㈣ volatile 修饰词 PICC 中还有一个特殊的变量修饰词“volatile”,用来 说明一个变量的值是会随机变化的,即使程序没有刻意对 它进行任何赋值操作。 在单片机中,作为输入的IO 端口其内容将是随意变 化的;很多特殊功能寄存器的值也将随着指令的运行而动 态改变。所有这种类型的变量必须将它们明确定义成 “volatile”类型,例如: volatile unsigned char STATUS @ 0x03; volatile bit commFlag;
Hitech-PICC 编译器基本上符合ANSI C标准,但是不 支持函数的递归调用。其主要原因是因为PIC 单片机特殊 的堆栈结构。PIC 单片机的堆栈是硬件实现的,其深度已 随芯片固定,无法实现需要大量堆栈操作的递归算法。
二、PICC C编译器的安装 PICC C编译器可以运行在Windows操作系统上,可 以在MPLAB IDE集成开发环境下进行项目开发。 下面介绍在MPLAB IDE 7.00集成环境下安装和设置 PICCV8.05 PL1 PICC编译器,以及在此环境下编译和调 试源程序的基本方法。
第3步:单击对话框中的Browse按钮,弹出如下图所示的 打开文件对话框。在缺省PICC V8.05PL1编译器安装目录 C:\HT-PIC\bin\下,选择plcc.exe作为编译程序。然后单击 “打开”按钮,可以发现PICC Compiler项已选择picc.exe 作为编译程序。
同样,PICC Assembler和PICC Linker都选择picc.exe 作为汇编和链接程序,如下图所示。
㈤标准库函数 PICC 提供了较完整的C 标准库函数支持,其中包括 数学运算函数和字符串操作函数。在程序中使用这些现成 的库函数时需要注意的是入口参数必须在bank0 中。 如果需要用到数学函数,则用 “#include <math.h>” 包含头文件;如果要使用字符串操作函数,就需要包含 “#include <string.h>”头文件。在这些头文件中提供了函 数类型的声明。直接查看这些头文件就可以知道PICC 提 供了哪些标准库函数。 C 语言中的格式化输出函数“printf/sprintf”用在单片 机的程序中时要特别谨慎。printf/sprintf 是一个非常大的 函数,一旦使用,你的程序代码长度就会增加很多。
pic单片机c语言编程
pic单片机c语言编程如何在单片机中使用C语言进行编程单片机是一种集成电路,具有微处理器核心、存储器、输入输出端口等基本功能。
它通过程序控制来实现各种应用,而C语言是一种高级编程语言,具有结构清晰、可读性强和可移植性好的特点。
将C语言与单片机相结合,可以方便地开发各种应用。
一、概述在单片机中使用C语言编程,需要具备以下几个基本环境:1. 开发环境:包括编译器和开发工具。
2. 单片机:根据不同的应用需求选择合适的单片机。
3. 硬件连接:将单片机与外围设备连接以实现相应的功能。
二、选择开发环境和编译器选择开发环境和编译器是进行单片机C语言编程的首要任务。
常用的开发环境有Keil、IAR Embedded Workbench等,它们都提供了C语言编译器和调试工具,方便开发者进行程序编写和调试。
选择合适的开发环境和编译器有助于提高开发效率和代码的可靠性。
三、学习单片机的基本知识在编写单片机C语言程序之前,需要对单片机的基本知识有一定了解。
包括单片机的架构、寄存器、存储器、时钟等方面的知识。
掌握这些基础知识对于编写高效、可靠的程序非常重要。
四、编写程序单片机的C语言程序主要分为两个部分:主函数和中断服务函数。
主函数是程序的主要入口,用于初始化各种硬件资源,并进行程序的主要逻辑处理。
中断服务函数则是在发生中断时由单片机自动调用的程序段,用于处理中断事件。
1. 编写主函数主函数是程序的入口函数,在程序的最开始进行一些初始化的操作。
例如,设置IO口的输入输出方向、初始化串口等。
接着,进入一个无限循环,用于处理程序的主要逻辑。
示例代码如下:c#include <reg52.h> 引入单片机头文件void main(){初始化操作while(1){程序的主要逻辑}}2. 编写中断服务函数中断服务函数是在中断事件发生时由单片机自动调用的函数,用于处理中断事件。
它需要在程序的开始处进行中断的配置和使能。
具体的中断服务函数的编写需要根据具体的应用需求进行。
PIC 单片机的C 语言编程
PIC单片机C语言编程讲义奥科电子工作室(内部资料)2006年元月第一版第1章 PIC 单片机的C 语言编程1.1 PIC 单片机C 语言编程简介用C 语言来开发单片机系统软件最大的好处是编写代码效率高、软件调试直观、维护升级方便、代码的重复利用率高、便于跨平台的代码移植等等,因此C 语言编程在单片机系统设计中已得到越来越广泛的运用。
针对PIC 单片机的软件开发,同样可以用C 语言实现。
但在单片机上用C 语言写程序和在PC 机上写程序绝对不能简单等同。
现在的PC 机资源十分丰富,运算能力强大,因此程序员在写PC 机的应用程序时几乎不用关心编译后的可执行代码在运行过程中需要占用多少系统资源,也基本不用担心运行效率有多高。
写单片机的C 程序最关键的一点是单片机内的资源非常有限,控制的实时性要求又很高,因此,如果没有对单片机体系结构和硬件资源作详尽的了解,以笔者的愚见认为是无法写出高质量实用的C 语言程序。
这就是为什么前面所有章节中的的示范代码全部用基础的汇编指令实现的原因,希望籍此能使读者对PIC 单片机的指令体系和硬件资源有深入了解,在这基础之上再来讨论C 语言编程,就有水到渠成的感觉。
本讲稿围绕中档系列PIC 单片机来展开讨论,Microchip 公司自己没有针对中低档系列PIC单片机的C 语言编译器,但很多专业的第三方公司有众多支持PIC 单片机的C 语言编译器提供,常见的有Hitech、CCS、IAR、Bytecraft 等公司。
其中笔者最常用的是Hitech 公司的PICC 编译器,它稳定可靠,编译生成的代码效率高,在用PIC 单片机进行系统设计和开发的工程师群体中得到广泛认可。
其正式完全版软件需要购置,但在其网站上有限时的试用版供用户评估。
另外,Hitech 公司针对广大PIC 的业余爱好者和初学者还提供了完全免费的学习版PICC-Lite 编译器套件,它的使用方式和完全版相同,只是支持的PIC 单片机型号限制在PIC16F84、PIC16F877 和PIC16F628 等几款。
PIC单片机的C语言应用下的函数库
PICC库函数本章将详细列出PICC编译器的库函数。
每个函数均从函数名开始,然后按照以下几个标题给出详细解释。
提要:函数的C语言定义以及定义函数的头文件。
描述:对函数及其目的进行叙述性描述。
例程:给出一个能说明该函数的应用例子。
数据类型:列出函数中使用的一些特殊的数据类型(如结构体等)的C语言定义。
这些数据类型的定义包含在提要标题下列出的头文件中。
参阅:给出相关联的函数。
返回值:如果函数有返回值,则在本标题下将给出返回值的类型和性质,同时还包括错误返回的信息。
1 ABS函数1. 提要#include <stdlib.h>int abs (int j)2. 描述abs( )函数返回变量j的绝对值。
3. 例程#include <stdio.h>#include <stdlib.h>voidmain (void){int a = -5;printf("The absolute value of %d is %d\n",a,abs(a));}4. 返回值j的绝对值。
2 ACOS函数1. 提要#include <math.h>double acos (double f)2. 描述acos( )函数是cos( ) 的反函数。
函数参数在[-1,1]区间内,返回值是一个用弧度表示的角度,而且该返回值的余弦值等于函数参数。
3. 例程#include <math.h>#include <stdio.h>/*以度为单位,打印[-1,1]区间内的反余弦值*/voidmain (void){float i,a;for(i = -1.0,i < 1.0;i += 0.1) {a = acos(i)*180.0/3.141592;printf("acos(%f) = %f degrees\n",i,a);}}4.参阅sin( ),cos( ),tan( ),asin( ),atan( ),atan2( )5.返回值返回值是一个用弧度表示的角度,区间是[0,π]。
pic的c语言使用
PIC的C语言使用在MPLAB-IDE中使用HitechC编译器一、装入编译器:1、启动MPLAB-IDE,如下图所示选择Project-》Install Language Tool2、在弹出的安装语言工具对话框里“Language Suite”选项现在显示的是Microchip,点击后面的箭头来选择语言。
我使用的工具是HI-TECH PICCME,所以选择为“HI-TEC H PICC”。
3、接下来在“Tool Name”里选择编译器组件的调用路径,这里有“PICC Compiler”(C编译器)、“PICC Assembler”(汇编器)和“PICC Linker”(链接器)3项都需要设置。
用“Browse”来选择调用路径,把上述3项组件的调用文件都设为PICC.EXE。
点“OK”后完成设置。
二、选用编译器:1、新建一个项目,编辑项目对话框的“Language Tool Suite”栏目默认是“Microchip”,将它改为“HI-TECH PICC”。
2、在项目文件框里点“flasha[.hex]”,这时“Node Properties”(节点属性)按钮将会亮起来。
点击进3、设置节点属性。
由于FLASHA.C还有其他相关连的源程序需要加进来,所以在“Language Tool”栏里应该选择“PICC Linker”(链接器)。
通常我们可以选择:1)Generate debug inf显示debug信息;2)Create map file:选择该项后我们将看到ROM、RAM 的使用情况;3)Error file:显示错误信息;4)Compile for MPLAB ICD:如果不使用ICD,就不必选择这个项目了。
4、设置完成之后点“Add Node”来添加节点。
这个项目有两个节点:fla.c和flasha.c,选择节点后点击“N ode Properties”或直接双击节点来进入节点属性设置。
PIC单片机C语言指南
PIC单片机C语言指南第一部分为了对PIC单片机有更好的支持,PICC在标准C的基础上作了一些扩充:z定义I/O函数,以便在你的硬件系统中使用中定义的函数。
z用C语言编写中断服务程序z用C语言编写I/O操作程序z C语言与汇编语言间的接口1-1 与标准C的不同PICC只在一处与标准C不同:函数的重入。
因为PIC单片机的寄存器及堆栈有限,所以PICC不支持可重入函数。
1-2 支持的PIC芯片PICC 支持很多PIC单片机,支持PIC单片机的类型在LIB目录下的picinfo.ini文件中有定义。
1-3 PICC 包含一些标准库1-4 PICC 编译器可以输出一些格式的目标文件,缺省设置为输出Bytecraft的'COD' 格式和 Intel的'HEX'格式。
你可以用表1-1中的命令来指定输出格式。
表1-1格式名称描述PICC 命令文件类型Motorola HEX S1/S9 type hex file -MOT .HEX Intel HEX Intel style hex records(缺省) -INTEL .HEX Binary Simple binary image -BIN .BIN UBROF Universal Binary Image Relocatable Format -UBROF .UBR Tektronix HEX Tektronix style hex records -TEK .HEX American Hex format with symbols for American -AAHEX .HEX Automation HEX Automation emulatorsBytecraft .COD Bytecraft code format(缺省) n/a(缺省) .COD Library HI-TECH library file n/a .LIB1-5 符号文件PICC -G 命令用于生成符号文件,有了符号文件,你就可以进行源程序调试.命令格式为:PICC -16F877 -G test.c在使用仿真器时必须使用-G命令。
PIC单片机C语言程序设计_1_
一、汇编语言与C语言早期的单片机程序多采用汇编语言编写。
用汇编语言编程,直接、简捷,可有效地访问和控制各种硬件设备,如存储器、I/O口等,目标代码简短、占用内存少、执行速度快、语句效率高。
然而,由于汇编语言是面向机器的语言,不同厂家或同厂家不同系列的单片机,其汇编语言指令系统往往互不相同,即通常所说的“不兼容”。
这就出现了精通51单片机汇编语言的人不能直接编写PIC或其他单片机的汇编语言源程序,反之亦然的现象,以及产品升级换代和不同单片机间程序移植难的问题。
而且,由于汇编语言是采用助记符的低级语言,可读性较差,当源程序功能多、程序长时,即使加了注释,阅读自己编写的程序也会感到困难,更不用说修改程序和增加功能了。
目前,单片机的应用越来越广,各半导体生产厂家不断推出各种高、中、低档单片机系列,以适应市场的需求。
而客户对单片机系统的设计人员的基本要求,就是要选择能够满足产品性能和成本要求的单片机,并以最快的速度开发出完全满足市场需求的智能化产品。
用汇编语言编程显然无法达到要求。
用C语言开发单片机系统软件的最大好处,是代码效率高、软件调试直观、维护升级方便、代码的重复利用率高、便于跨平台的代码移植等。
因此,C语言在单片机系统设计中得到越来越广泛的运用。
C语言是一种高级语言,具有低级语言的特点,原来用各种汇编语言编写的单片机程序,均可用C 语言程序代换。
二、C语言的特点C语言的特点可归纳如下。
1.语言简洁C是一种小型语言,共有32个关键字,9种控制语句,表示方法简单,只需用规范的方法,就可以构造出功能很强的数据类型、语句和程序结构。
如用++表示加1;--表示减1;运算符省写等。
2.表达方式灵活实用C语言提供多种运算符和表达式值的方法,对问题的表达可通过多种途径获得,其程序设计更主动、灵活。
它语法限制不太严格,程序设计自由度大,如对整型量与字符型数据及逻辑型数据可以通用等。
3.表达力强C语言有丰富的数据结构和运算符。
PIC单片机的C语言编程指南
PIC单片机C语言编程实例
/*等待中断*/
1.1.2 程序清单
下面给出一个调试通过的例程,可作为读者的参考。调试该程序把模板 J7 上的短路跳 针拔下,以免产生冲突。
#include <pic1687x.h>
volatile unsigned char data;
TRISC=0x00;
/*SDO 引脚为输出,SCK 引脚为输出*/
}
1.2.3 程序清单
下面给出已经在实验板上调试通过的一个程序,可作为用户编制其它程序的参考。
#include
<pic1687x.h>
/*该程序用于在 8 个 LED 上依次显示 1~8 等 8 个字符*/
static volatile int table[20]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0XD8,0x80,
I;
unsigned char j;
const char table[20]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0XD8,0x80,0x90,
0x88,0x83,0xc6,0xa1,0x86,0x8e,0x7f,0xbf,0x89,0xff};
/*B 口“电平变化中断”初始化子程序*/
/*启动发送*/
do
{
;
}while(SSPIF==0);
/*等待发送完毕*/
SSPIF=0;
/*清除 SSPIF 标志*/
}
/*主程序*/
main()
{
unsigned I;
initial();
PIC单片机C语言编程实例
PIC单片机C语言编程实例——液晶显示模块编程15.2.2MG-12232模块的编程下面以图15.1的接口电路为例。
液晶显示区域分成E1边和E2边,下面只含E1边的程序(表15.1中E1=1,E2=0),E2边(表15.1中E1=0,E2=1)类推。
在系统程序的初始化部分,应对程序中用到的寄存器和临时变量作说明,如:unsignedcharTRANS;unsignedcharPAGEADD;//存放页地址寄存器unsignedcharPAGENUM;//存放总页数寄存器unsignedcharCLMSUM;//存放总列数寄存器unsignedcharCLMADD;//存放列地址寄存器unsignedcharWRITE;//存放显示数据寄存器unsignedcharrow;//存放显示起始行寄存器unsignedchari,k;//通用寄存器//系统各口的输入输出状态初始化子程序voidINITIAL(){ADCON1=0X87;//设置PORTA口和PORTE口为数字I/O口TRISB0=0;TRISE=0X00;//设置液晶的4个控制脚为输出}//读液晶显示器状态子程序voidLCDSTA1(){while(1){TRISD=0XFF;//设置D口为输入RB0=1;//E1=1RA3=0;//E2=0RE0=1;//R/W=1RE1=0;//A0=0if(RD7==0)break;//为忙状态,则继续等待其为空闲}}//对液晶显示器发指令子程序(指令保存在TRANS寄存器中){LCDSTA1();//判断液晶是否为忙TRISD=0X00;//置D口为输出RB0=1;//E1=1RA3=0;//E2=0RE0=0;//R/W=0RE1=0;//A0=0PORTD=TRANS;//需要写入的命令字送入数据线RB0=0;//E1=0写入指令RE0=1;//R/W=1}//对液晶显示器写数据子程序(数据保存在WRITE寄存器中) voidWRITE1(){TRANS=CLMADD;//设置列地址TRANS1();LCDSTA1();//查询液晶是否为空闲TRISD=0X00;//D口为输出RB0=1;//E1=1RA3=0;//E2=0RE0=0;//R/W=0RE1=1;//A0=1PORTD=WRITE;//需要写入的数据放入D口RB0=0;//E1=0,写入数据CLMADD++;//列地址加1RE0=1;//R/W=1}//开E1显示子程序voidDISP1(){while(1){TRANS=0XAF;TRANS1();//送出控制命令LCDSTA1();//判断液晶是否为空闲TRISD=0XFF;//设置D口为输入RB0=1;//E1=1RA3=0;//E2=0RE0=1;//R/W=1RE1=0;//A0=0if(RD5==0)break;//如果液晶没被关闭,则继续关}}//E1边清屏子程序voidCLEAR1(){PAGEADD=0xB8;//设置页地址代码for(PAGENUM=0X04;PAGENUM>0;PAGENUM-){ TRANS=PAGEADD;TRANS1();CLMADD=0x00;//设置起始列for(CLMSUM=0X50;CLMSUM>0;CLMSUM-){ LCDSTA1();//判断液晶是否为空闲WRITE=0X00;WRITE1();//写入00H以清屏}PAGEADD++;//页号增1}}//关E1显示子程序voidDISOFF1(){while(1){TRANS=0XAE;TRANS1();//发出控制命令LCDSTA1();//判断液晶是否为空闲TRISD=0XFF;//D口设置为输入RB0=1;//E1=1RA3=0;//E2=0RE0=1;//R/W=1RE1=0;//A0=0if(RD5==1)break;//如果液晶没被关闭,则继续关}}有了以上的通用子程序,就可以构造出各种显示程序,如字符。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
PICC库函数本章将详细列出PICC编译器的库函数。
每个函数均从函数名开始,然后按照以下几个标题给出详细解释。
提要:函数的C语言定义以及定义函数的头文件。
描述:对函数及其目的进行叙述性描述。
例程:给出一个能说明该函数的应用例子。
数据类型:列出函数中使用的一些特殊的数据类型(如结构体等)的C语言定义。
这些数据类型的定义包含在提要标题下列出的头文件中。
参阅:给出相关联的函数。
返回值:如果函数有返回值,则在本标题下将给出返回值的类型和性质,同时还包括错误返回的信息。
1 ABS函数1. 提要#include <stdlib.h>int abs (int j)2. 描述abs( )函数返回变量j的绝对值。
3. 例程#include <stdio.h>#include <stdlib.h>voidmain (void){int a = -5;printf("The absolute value of %d is %d\n",a,abs(a));}4. 返回值j的绝对值。
2 ACOS函数1. 提要#include <math.h>double acos (double f)2. 描述acos( )函数是cos( ) 的反函数。
函数参数在[-1,1]区间内,返回值是一个用弧度表示的角度,而且该返回值的余弦值等于函数参数。
3. 例程#include <math.h>#include <stdio.h>/*以度为单位,打印[-1,1]区间内的反余弦值*/voidmain (void){float i,a;for(i = -1.0,i < 1.0;i += 0.1) {a = acos(i)*180.0/3.141592;printf("acos(%f) = %f degrees\n",i,a);}}4.参阅sin( ),cos( ),tan( ),asin( ),atan( ),atan2( )5.返回值返回值是一个用弧度表示的角度,区间是[0,π]。
如果函数参数超出区间[-1,1],则返回值将为0。
3 ASCTIME函数1. 提要#include <time.h>char * asctime (struct tm * t)2. 描述asctime( )函数通过指针t 从上struct tm结构体中获得时间,返回描述当前日期和时间的26个字符串,其格式如下:Sun Sep 16 01:03:52 1973\n\0值得注意的是,在字符串的末尾有换行符。
字符串中的每个字长是固定的。
以下例程得到当前时间,通过localtime( )函数将其转换成一个struct tm指针,最后转换成ASCII码并打印出来。
其中,time( )函数需要用户提供(详情请参阅time( )函数)。
3. 例程#include <stdio.h>#include <time.h>voidmain (void){time_t clock;struct tm * tp;time(&clock);tp = localtime(&clock);printf("%s",asctime(tp));}4. 参阅ctime( ),gmtime( ),localtime( ),time( )5. 返回值指向字符串的指针。
注意:由于编译器不提供time( )例行程序,故在本例程中它需要由用户提供。
详情请参照time( )函数。
6. 数据类型struct tm {int tm_sec;int tm_min;int tm_hour;int tm_mday;int tm_mon;int tm_year;int tm_wday;int tm_yday;int tm_isdst;};4 ASIN函数1. 提要#include <math.h>double asin (double f)2. 描述asin( )函数是sin( )的反函数。
它的函数参数在[-1,1]区间内,返回一个用弧度表示的角度值,而且这个返回值的正弦等于函数参数。
3. 例程#include <math.h>#include <stdio.h>voidmain (void){float i,a;for(i = -1.0;i < 1.0 ;i += 0.1) {a = asin(i)*180.0/3.141592;printf("asin(%f) = %f degrees\n",i,a);}}4. 参阅sin( ),cos( ),tan( ),acos( ),atan( ),atan2( )5. 返回值本函数返回一个用弧度表示的角度值,其区间为[-π/2,π/2]。
如果函数参数的值超出区间[-1,1],则函数返回值将为0。
5 ATAN函数1. 提要#include <math.h>double atan (double x)2. 描述函数返回参数的反正切值。
也就是说,本函数将返回一个在区间[-π/2,π/2]的角度e,而且有tan(e)=x(x为函数参数)。
3. 例程#include <stdio.h>#include <math.h>voidmain (void){printf("%f\n",atan(1.5));}4. 参阅sin( ),cos( ),tan( ),asin( ),acos( ),atan2( )5. 返回值返回函数参数的反正切值。
6 ATAN2函数1. 提要#include <math.h>double atan2 (double y,double x)2. 描述本函数返回y/x的反正切值,并由两个函数参数的符号来决定返回值的象限。
3. 例程#include <stdio.h>#include <math.h>voidmain (void){printf("%f\n",atan2(1.5,1));}4. 参阅sin( ),cos( ),tan( ),asin( ),acos( ),atan( )5. 返回值返回y/x的反正切值(用弧度表示),区间为[-π,π]。
如果y和x均为0,将出现定义域错误,并返回0。
7 ATOF函数1. 提要#include <stdlib.h>double atof (const char * s)2. 描述atof( )函数将扫描由函数参数传递过来的字符串,并跳过字符串开头的空格。
然后将一个数的ASCII表达式转换成双精度数。
这个数可以用十进制数、浮点数或者科学记数法表示。
3. 例程#include <stdlib.h>#include <stdio.h>voidmain (void){char buf[80];double i;gets(buf);i = atof(buf);printf("Read %s: converted to %f\n",buf,i);}4. 参阅atoi( ),atol( )5. 返回值本函数返回一个双精度浮点数。
如果字符串中没有发现任何数字,则返回0.0。
8 ATOI函数1. 提要#include <stdlib.h>int atoi (const char * s)2. 描述atoi( )函数扫描传递过来的字符串,跳过开头的空格并读取其符号;然后将一个十进制数的ASCII表达式转换成整数。
3. 例程#include <stdlib.h>#include <stdio.h>voidmain (void){char buf[80];int i;gets(buf);i = atoi(buf);printf("Read %s: converted to %d\n",buf,i);}4. 参阅xtoi( ),atof( ),atol( )5. 返回值返回一个有符号的整数。
如果在字符串中没有发现任何数字,则返回0。
9 ATOL函数1.提要#include <stdlib.h>long atol (const char * s)2.描述atol( )函数扫描传递过来的字符串,并跳过字符串开头的空格;然后将十进制数的ASCII表达式转换成长整型。
3.例程#include <stdlib.h>#include <stdio.h>voidmain (void){char buf[80];long i;gets(buf);i = atol(buf);printf("Read %s: converted to %ld\n",buf,i);}4.参阅atoi( ),atof( )5.返回值返回一个长整型数。
如果字符串中没有发现任何数字,返回值为0。
10 CEIL函数1. 提要#include <math.h>double ceil (double f)2. 描述本函数对函数参数f 取整,取整后的返回值为大于或等于f 的最小整数。
3. 例程#include <stdio.h>#include <math.h>voidmain (void){double j;scanf("%lf",&j);printf("The ceiling of %lf is %lf\n",j,ceil(j));}11 COS函数1. 提要#include <math.h>double cos (double f)2. 描述本函数将计算函数参数的余弦值。
其中,函数参数用弧度表示。
余弦值通过多项式级数近似值展开式算得。
3. 例程#include <math.h>#include <stdio.h>#define C 3.141592/180.0voidmain (void){double i;for(i = 0;i <= 180.0;i += 10)printf("sin(%3.0f) = %f,cos = %f\n",i,sin(i*C),cos(i*C));}4. 参阅sin( ),tan( ),asin( ),acos( ),atan( ),atan2( )5. 返回值返回一个双精度数,区间为[-1,1]。