PIC单片机的交流电压测量C语言实例
PIC单片机C语言编程实例一
}
/*系统各输入输出口初始化子程序*/
voidinitial()
{
TRISA=0xDF;
TRISB=0XF0;/*设置与键盘有关的各口的数据方向*/
INTCON=0x00;/*关闭所有中断*/
data=0X00;/*待显示的寄存器赋初值*/
PORTA_5=0;/*LACK送低电平,为锁存做准备*/
}
/*SPI发送子程序*/
voidSPILED(int data)
{
SSPBUF=data;/*启动发送*/
do
{
;
}while(SSPIF==0);/*等待发送完毕*/
SSPIF=0;/*清除SSPIF标志*/
}
/*主程序*/
main()
{
data=table[j];/*获得需要送出显示的段码*/
RA5=0;/*LACK信号清0,为锁存做准备*/
SPILED(data);
RA5=1;/*最后给一个锁存信号,代表显示任务完成*/
}
/*中断服务程序*/
voidinterruptkeyint(void)
{
DELAY();/*软件延时*/
if ((RB5==0)||(RB4==0))/*该语句除了能够确认按键是否为干扰外,*/
}/*等待有键按下*/
DELAY();/*软件延时*/
if ((PORTB_5==0)||(PORTB_4==0))
KEYSERVE();/*如果仍有键按下,则调用键服务子程序*/
elsej=0x00;/*如果为干扰,则令返回值为0*/
return(j);
}
PIC单片机的C语言编程指南
PIC单片机的C语言编程指南PIC单片机是一种常用的嵌入式系统开发平台,其具有低功耗、成本低廉、易于编程等优点,在工业自动化、电子设备控制等领域有着广泛应用。
本文将为读者提供一份PIC单片机的C语言编程指南,帮助初学者快速入门并掌握基本的编程技巧。
首先,我们需要了解一些PIC单片机的基本概念。
PIC单片机采用哈佛结构,具有多种型号和系列,每个系列有多个型号可供选择。
不同的型号和系列有不同的特性和功能,因此在编程时需要根据具体的芯片型号进行适配。
PIC单片机的编程语言常用的是C语言,其语法简洁,易于理解和学习,并且具有较高的可移植性。
在编写PIC单片机的C语言程序时,我们需要按照以下步骤进行:1. 引入头文件:使用#include指令引入所需的头文件,头文件包含了定义和声明所需的函数和变量。
3.初始化:在程序开始时对所需的资源进行初始化,包括引脚配置、中断设置、定时器初始化等。
4.主循环:编写主循环代码,其中包括需要重复执行的功能,例如读取传感器数据、处理输入输出等。
5.中断处理:根据需要,编写中断处理函数,处理外部中断、定时器中断等。
6.清理工作:在程序结束时,进行一些清理工作,例如释放资源、关闭设备等。
下面是一个PIC单片机的C语言编程示例:```c#include <xc.h> // 引入XC8编译器的头文件#define LED_PIN RC0 // 定义LED连接的引脚void iniTRISC0=0;//配置RC0引脚为输出模式void maiinit(; // 初始化while(1)LED_PIN=1;//点亮LED__delay_ms(500); // 延时500毫秒LED_PIN=0;//关闭LED__delay_ms(500); // 延时500毫秒}```上述代码实现了一个简单的功能,即使LED灯以500毫秒的间隔交替点亮和关闭。
在程序中,我们首先引入了`<xc.h>`头文件,然后定义了一个宏`LED_PIN`来表示连接LED的RC0引脚。
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语言使用(一)
PIC单片机的C语言使用(一)在MPLAB-IDE 中使用HitechC 编译器一、装入编译器:1、启动MPLAB-IDE,如下图所示选择Project-》Install Language Toolscreen.width-300)this.width=screen.width-300” border=0>2、在弹出的安装语言工具对话框里“Language Suite”选项现在显示的是Microchip,点击后面的箭头来选择语言。
screen.width-300) this.width=screen.width-300” border=0>我使用的工具是HI-TECH PICCME,所以选择为“HI-TECH PICC”。
3、接下来在“Tool Name”里选择编译器组件的调用路径,这里有“PICC Compiler”(C 编译器)、“PICC Assembler”(汇编器)和“PICC Linker”(链接器)3 项都需要设置。
screen.width-300)this.width=screen.width-300” border=0>用“Browse”来选择调用路径,把上述3 项组件的调用文件都设为PICC.EXE。
点“OK”后完成设置。
screen.width-300)this.width=screen.width-300” border=0>二、选用编译器:1、新建一个项目,编辑项目对话框的“Language Tool Suite”栏目默认是“Microchip”,将它改为“HI-TECH PICC”。
screen.width-300)this.width=screen.width-300” border=0>2、在项目文件框里点“flasha[.hex]”,这时“Node Properties”(节点属性)按钮将会亮起来。
点击进入。
screen.width-300)this.width=screen.width-300”border=0>3、设置节点属性。
单片机数字电压表(带仿真图C程序)
基于51单片机数字电压表本模块采用ADC0832模数转换芯片,LCD1602液晶显示,测量范围0-5V,精度误差0.01V看了很多网上的课程设计或者毕业论文,得出以下几点:1.数字电压表的方案有很多种,有的采用ADC0809,或者ADC0808等,他们都是8温AD,并口传输数据,具有速率高的优点。
但是硬件复杂,与单片机电路繁琐,焊接起来比较麻烦。
所以本设计采用ADC0832,同样8位AD,特点是串口传输数据,硬件接口简单,且精度误差一致,速率也比较快,对于要求不高的系统非常适合。
2.显示电路,网上采用LED显示居多,本设计采用LCD1602液晶显示,具有硬件搭设简单,显示美观等优点3.本设计方便移植,只需将LCD1602三个控制端口,ADC0832 四个控制端口修改即可。
注意LCD1602数据传输接口是单片机的P0口,如下图,需要接上拉电阻4.程序采用C代码编写,亲测直接可以使用,若需仿真文件,请用E-mail联系邮系。
邮箱:gnsywb@5.网上很多设计数据转换程序有误,不够正确。
在转换过程中,中间变量需设置为int 类型,虽然8位AD输出最高位255,但是余数转换过程中会大于255。
若设计char型,会造成显示输出有误。
void convert(uchar a){ uint temp; //特别注意这里需定义int型(余数将大于255)dis[0]=a/51; //取个位temp=a%51;temp=temp*10; dis[1]=temp/51; //取小数点后第一位temp=temp%51;temp=temp*10; dis[2]=temp/51; //取小数点后第二位}具体电路图如下:1.利用电压表与测量显示电压对比附录:C程序/******************************************** 功能:单片机数字电压表ADC0832+LCD16021,测量范围0-5V2,2路输入电压,可自行设定3,测量精度误差0.01V,LCD液晶显示编写者:小子在西藏gnsywb@编写日期:2012-11-5*********************************************/ #include <reg52.h>#include <intrins.h>#define uint unsigned int#define uchar unsigned charsbit lcdrs=P2^4;sbit lcdrw=P2^5;sbit lcden=P2^6; //1602控制端口sbit DI=P3^4;sbit DO=P3^4; //DI和DO与单片机共接口sbit Clk=P3^3;sbit CS=P3^5;//ADC0832控制端口uchar dis[3]={0x00,0x00,0x00}; //显示缓冲区uchar date=0; //AD值uchar CH; //ADC0832通道值/*****************************************AD0832转换程序******************************************/uchar ADC0832(uchar CH){uchar i,dis0,dis1;Clk=0; //拉低时钟DI=1; //初始化_nop_();CS=0; //芯片选定_nop_();Clk=1; //拉高时钟_nop_();if(CH==0) //通道选择{Clk=0; //第一次拉低时钟DI=1; //通道0的第一位_nop_();Clk=1; //拉高时钟_nop_();Clk=0; //第二次拉低时钟,ADC0832 DI接受数据DI=0; //通道0的第二位_nop_();Clk=1;_nop_();}else{Clk=0;DI=1; //通道1的第一位_nop_();Clk=1;_nop_();Clk=0;DI=1; //通道1的第二位_nop_();Clk=1;_nop_();}Clk=0; //第三次拉低时钟,此前DI两次赋值决定通道DI=1; //DI开始失效,拉高电平,便于DO数据传输for(i= 0;i<8;i++) //读取前8位的值{_nop_();dis0<<= 1;Clk=1;_nop_();Clk=0;if (DO)dis0|=0x01;elsedis0|=0x00;}for (i=0;i<8;i++) //读取后8位的值{dis1>>= 1;if (DO)dis1|= 0x80;elsedis1|= 0x00;_nop_();Clk=1;_nop_();Clk=0;}if(dis0==dis1) //两次结束数据比较,若相等date=dis0; //则赋值给dat_nop_();CS=1; //释放ADC0832DO=1; //拉高输出端,方便下次通道选择DI端有效Clk=1; //拉高时钟return date;}/***********************************************数据转换程序功能:将0-255级换算成0.00-5.00的电压数***********************************************/void convert(uchar a){uint temp; //特别注意这里需定义int型(余数将大于255)dis[0]=a/51; //取个位temp=a%51;temp=temp*10;dis[1]=temp/51; //取小数点后第一位temp=temp%51;temp=temp*10;dis[2]=temp/51; //取小数点后第二位}/***************************************** LCD1602驱动程序******************************************/ void delay(uchar z){uint x,y;for(x=z;x>0;x--)for(y=122;y>0;y--);}void write_cmd(uchar cmd)//lcd1602写命令函数{lcdrs=0;lcdrw=0; //选择指令寄存器lcden=1;P0=cmd; //写数据delay(5);lcden=0; //使能拉低lcden=1;}void write_date(uchar date)//lcd1602写数据函数{lcdrs=1;lcdrw=0; //选择数据寄存器lcden=1;P0=date; //写数据delay(5);lcden=0; //使能拉低lcden=1;}void init_lcd1602()//lcd1602初始化{write_cmd(0x01); //清屏write_cmd(0x38); //功能设置write_cmd(0x0c); //显示设置write_cmd(0x06); //输入方式从左到右delay(1);}/***************************************** 显示函数*****************************************/ void display(void){uchar i;write_cmd(0x80);for(i=0;i<3;i++){if(i==1) write_date('.'); //第二位显示小数点write_date (0x30+dis[i]);delay(5);}write_date('V'); //最后一位后显示字符'V'}/************************************************ 主函数***************************************************/ void main(void){CH=0; //选择通道0或1init_lcd1602();//液晶1602显示初始化while(1) //主循环{date=ADC0832(CH);//启动ADC0832转换并接受数据delay(1);convert(date); //数据转换成BCD码display(); //显示数值}}。
一种基于PIC单片机电压采样的功率因数在线检测
一种基于PIC单片机电压采样的功率因数在线检测1.引言功率因数是交流电路中的重要参数,是衡量电力系统是否经济运行的一个重要指标,也是供电线路在线监测系统的重要检测量,在功率因数补偿系统中需对其进行实时测量[1]。
因此设计出结构简单、检测精度高的功率因数在线检测电路十分必要。
而功率因数的测量一般都要对被测电路的电压、电流进行采样,然后进行处理提取功率因数信号,通常由电压、电流取样电路、整形电路、同步周期测量、相位测量等组成,其缺点是结构较复杂,检修困难,有时会出现功率因数的测量精度不高的问题[2]。
为此,作者基于电压采样,经单片机软件进行分析、计算可得出被测电路的功率因数,通过显示电路显示出功率因数的大小,并由通信接口电路将被测功率因数进行远距离传输。
这样既简化功率因数测量电路的结构,提高功率因数的测量精度,又增强了功率因数检测电路的功能。
2.原理分析通过对电压的提取来检测功率因数的原理如图 1 (a)所示,首先采用 3 个高精度的WB 系列数字式交流电压真有效值传感器分别对被测电路的电源电压U1、附加可调电阻RP 两端电压U2 及负载电压U3 进行检测。
可调电阻RP 的作用是使附加电阻尽可能小,以减小对被测负载的影响,又可得到数值适当的电压U2 满足功率因数计算的要求。
由电路理论[3],可画出电压1、2和3的相量图如图1(b)所示,则COSϕ即是被测负载的功率因数。
500)this.style.width=500;” border=0>图 1 电压测量原理示意图与电压相量图根据几何学中的余弦定理可得,500)this.style.width=500;” border=0>由式(2)可知,只要将电压U1、U2、U3 经过运算后就可求出负载的功率因数COSϕ。
为减小测量电路的硬件开销,数据的处理与计算由单片机软件完成。
3.单片机输入输出电路设计单片机输入输出电路主要是对传感器检测。
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 是一个非常大的 函数,一旦使用,你的程序代码长度就会增加很多。
交流电压测量C源程序-句句带注释
交流电压测量程序清单该程序已在模板上调试通过,可作读者的参考。
有关显示部分请读者参考本书相关章节,有关A/D转换的详细设置请参考前面章节。
#include <pic.h>#include <math.h>#include <stdio.h>//该程序用于测电网的交流电压有效值,最后的结果将在4个LED上显示,保留//1位小数。
//为了保证调试时数据运算的精确性,需要将PICC的double型数据选成32位union adres{int y1;unsigned char adre[2];}adresult;//定义一个共用体bank3 int re[40];//定义存放A/D转换结果的数组,在bank3中unsigned char k,data;//定义几个通用寄存器double squ ,squad;//平方寄存器和平方和寄存器,squ又通用为存储其//它数值int uo;bank1 unsigned chars[4];//此数组用于存储需要显示的字符的ASII码const char table[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0XD8,0x80,0x90};//不带小数点的显示段码表const char table0[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};//带小数点的显示段码表//A/D转换初始化子程序void adinitial(){ADCON0=0x41;//选择A/D通道为RA0,且打开A/D转换器//在工作状态,使A/D转换时钟为8Tosc ADCON1=0X8E;//转换结果右移,及ADRESH寄存器的高6位为"0"//把RA0口设置为模拟量输入方式ADIE=1;//A/D转换中断允许PEIE=1;//外围中断允许TRISA0=1;//设置RA0为输入方式}186//spi方式显示初始化子程序void SPIINIT(){PIR1=0;SSPCON=0x30;SSPSTA T=0xC0;//设置SPI的控制方式,允许SSP方式,并且时钟下降沿发送,与"74HC595,当其//SCLK从低到高跳变时,串行输入寄存器"的特点相对应TRISC=0xD7;//SDO引脚为输出,SCK引脚为输出TRISA5=0;//RA5引脚设置为输出,以输出显示锁存信号}//系统其它初始化子程序void initial(){CCP2IE=0;//禁止CCP中断SSPIE=0;//禁止SSP中断CCP2CON=0X0B;//初始化CCP2CON,CCP2为特别事件触发方式CCPR2H=0X01;CCPR2L=0XF4;//初始化CCPR2寄存器,设置采样间隔500 μs,//一个周期内电压采40个点}//中断服务程序void interrupt adint(void){CCP2IF=0;ADIF=0;//清除中断标志adresult.adre[0]=ADRESL;adresult.adre[1]=ADRESH;//读取并存储A/D转换结果,A/D转换的结果//通过共用体的形式放入了变量y1中re[k]=adresult.y1;//1次A/D转换的结果存入数组k++;//数组访问指针加1}//SPI传送数据子程序void SPILED(data){SSPBUF=data;//启动发送do{;187}while(SSPIF==0);SSPIF=0;}//主程序main( ){adinitial();//A/D转换初始化SPIINIT();//spi方式显示初始化initial();//系统其它初始化while(1){k=0;//数组访问指针赋初值TMR1H=0X00 ;TMR1L=0X00;//定时器1清0ei();//中断允许T1CON=0X01;//打开定时器1while(1){if(k==40) break;//A/D转换次数达到40,则终止}di();//禁止中断for(k=0;k<40;k++)re[k]=re[k]-0X199;//假设提升电压为2 V,对应十六进制数199H,//则需在采样值的基础上减去该值for(k=0,squad=0;k<40;k++) {uo=re[k];squ=(double)uo;//强制把采得的数据量转换成双精度数,以便运算squ=squ*5/1023;//把每点的数据转换成实际数据squ=squ*squ;//求一点电压的平方squad=squad+squ;} //以上求得40点电压的平方和,存于寄存器squad中squ=squad/40;//求得平均值squ=sqrt(squ);//开平方,求得最后的电压值squ=squ*154.054;//通过变压器的变比和分压电阻分配确定该系数//以上得到了实际电网的电压值squ=squ*10;//为了保证显示的小数点的精度,先对电压值乘以10uo=(int)squ;//强制把U转换成有符号整型量sprintf(s,"%4d",uo);//通过sprintf函数把需要显示的电压数据转换成//ASII码,并存于数组S中RA5=0;//准备锁存for(k=0;k<4;k++){188data=s[k];data=data&0X0F;//通过按位相与的形式把ASII码转换成BCD码if(k==2) data=table0[data];//因为squ已乘以10,则需在第2位打小数点else data=table[data];// table0存储带小数点的显示段码,//table存储不带小数点的显示段码SPILED(data);//发送显示段码}for(k=0;k<4;k++) {data=0xFF;SPILED(data);//连续发送4个DARK,使显示看起来好看一些,这点与//该实验板的LED分布结构有关}RA5=1;//最后给一个锁存信号,代表显示任务完成}}各位亲,够详细吧!…………………………………………………………………..各位亲,够详细吧!…………………………………………………………………..各位亲,够详细吧!…………………………………………………………………..189各位亲,够详细吧!…………………………………………………………………..各位亲,够详细吧!…………………………………………………………………..190191。
PIC单片机的C语言使用(一)——在MPLAB-IDE中使用HitechC编译器
一、装入编译器:1、启动MPLAB-IDE,如下图所示选择Project-》Install Language2、在弹出的安装语言工具对话框里“Language Suite”选项现在显示的是Microchip,点击后面的箭头来选择语言。
我使用的工具是HI-TECH PICCME,所以选择为“HI-TECH PICC”。
3、接下来在“Tool Name”里选择编译器组件的调用路径,这里有“PICC Compiler”(C编译器)、“PICC Assemble Linker”(链接器)3项都需要设置。
用“Browse”来选择调用路径,把上述3项组件的调用文件都设为PICC.EXE。
点“OK”后完成设置。
二、选用编译器:1、新建一个项目,编辑项目对话框的“Language Tool Suite”栏目默认是“Microchip”,将它改为“HI-TECHPICC”。
2、在项目文件框里点“flasha[.hex]”,这时“Node Properties”(节点属性)按钮将会亮起来。
点击进入。
3、设置节点属性。
由于FLASHA.C还有其他相关连的源程序需要加进来,所以在“Language Tool”栏里应该选择“PICC Linker”(链接器)。
通常我们可以选择:1)Generate debug info:显示debug信息;2)Create map file:选择该项后我们将看到ROM、RAM的使用情况;3)Error file:显示错误信息;4)Compile for MPLAB ICD:如果不使用ICD,就不必选择这个项目了。
4、设置完成之后点“Add Node”来添加节点。
这个项目有两个节点:fla.c和flasha.c,选择节点后点击“Node Properties”或直接双击节点来进入节点属性设置。
5、节点文件的工具这时应该选择为“PICC Compiler”(C编译器),蓝色圈子里的4项依次是:1)显示debug 信息;2)局部优化;3)全局优化;4)ICD编译配件。
PIC单片机C语言程序设计_3_
4 . o一 h ie 语句 d w l
格式 : do
eont jnue : 1
/ 转 向下次循环
对 照本连载 2009 年 10 期 56 页的程 序实例 中 的 fo 语 句 , 由该程序 中 , 点 亮 LE O 的延时是 一个 r 固定 值 , 所 以来 用 无参 数 延 时 (d e a ) 函数 vo d ly i de ay ( )"其 f 语 句 中的 k 是基 本 的整型 变量 i l r o t n 型 , 故取值上限不应超过 两个 字节 ( 见本连载 2009 年 1 期的表 3 )"在该实例 中, k=20000 "k 值越大 ,
P O R T B 二o x F B ;
/ 给 B 口赋值 B . 11111 11 . 0 d el ay(20000):/ 延时 /
P O R T B 二O xF 7 ;
/ 给 B 口赋值 B . 11110 111 .
de } ay(20000);/ 延时 /
P O R T B 二o x E F ;
下 SA =Ox3F / 以下是口的初始化 I R ;
T R } B 二 x0o; S o
I T C O N =oxOO; N P O R T B = 0 x0 0 ; P O R T B 二o xF F ;
的图 1 为例 加 以说 明 "从 中读者可 以看到 , 点 亮多 个 LE O 灯 的 C 程序 有 多种 编 写方式 , 均可达 到相 同的功能 "
58
电多翻乍2009年. 1 四 2
谈 份牛尸 O比
e 周拢
+; 素 都是 整型 变量 的 in ( 类 型 说 明符 )"对 于一 t 维 数 组 , 在 数组 定 义 时还 需 对数 组 赋 值 , 这 种赋 值 称 为对 数 组 的初 始化 "对 数组 初 始 化 , 常 用 三
基于PIC单片机使用C语言实现对交流电中电压、电流分析
基于PIC单片机使用C语言实现对交流电中电压、电流分析摘要:电学参量测量技术涉及范围广,特别是电压、电流表广泛适用于学校、工业、科研、国防等各种领域,供实验室和工业现场测试用。
随着电子技术的发展,在数字化、智能化、科技化为主的今天。
数字电压、电流表已成为电压、电流表设计的主要方向,在当前电压、电流测量系统中占有非常重要的位置。
我们在分析研究和总结了单片机技术的发展历史及趋势的基础上,以实用、可靠、经济等设计原则为目标,设计出全数字化测量电压电流装置。
本设计所完成的全数字电压、电流表将所测信号通过数据采集、数制处理,通过单片机控制最终使其相应值显示在四位串行数码管上,并同时利用串口发送给计算机,并以适时波形显示。
而且此设计通过对被测信号的判断和量程选择器的控制,实现了在高精度仪表中的八个档位的量程自动调节,既保证了弱信号的测量精度又兼顾了强信号的测量范围。
同时,克服了在采用传统的手动选择量程档位的电压、电流表时,忘记转换档位而造成仪表测量精度的下降或损坏的危险。
系统主要以单片pic18f452为控制核心,整个系统由中央控制模块、量程自动转换模块、A/D模数转换模块、LED显示模块和串口通信模块组成。
可实现对待测电压、电流的测量,在数码管上显示。
关键词:pic185f452 电压电流有效值最大值设计要求概述:A、以18F452单片机为核心芯片,设计一个单通道模拟电压、电流采集电路,要求对所接通道变化的模拟电压、电流值进行采集,采集来的数字量一路送至液晶显示,通过相关转换在液晶上显示出来;B、能够对直流电压与电流进行相应的采集和转换;C、利用lcd对电压值进行显示,精确到小数点后三位;D、设计系统的硬件与软件电路,并写出相关程序进行调试;E、画出电路图;F、完成对设计方案的论证,并做好分析和总结工作。
第一章电压、电流信号分析1.1 电压、电流信号的客观现象交流电的有效值是根据电流的热效应来规定的, 如果让交流电和直流电通过同样阻值的电阻, 如果它们在同一时间内产生的热量相等, 这一交流电电流的有效值就与这个直流电的电流数值相等.理论分析表明, 交流电流的有效值的定义式为,由此可知,交流电流的有效值等于电流瞬时值的平方在一周期内平均值的平方根, 因此有效值又称为均根值平均值是指在一个周期内交流电的绝对值的平均值。
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单片机的交流电源掉电检测系统
企业:控制网日期:2006-07-26领域:点击数:6681、引言在电力系统中,三相交流电源发生一相或多相掉电是十分恶劣的事件,有可能对系统产生严重的影响,影响正常的生产生活,若能在掉电时及时检测到电源的跌落,并将掉电时间、上电的时间等系统的重要数据保存在由备用电池供电的RAM中,则在供电恢复后可以保证系统的继续正常工作。
本文所介绍的系统就是能完成上述的各项功能。
2、系统的总体硬件设计以下是系统的主要硬件部分:图 1 系统的电源图1是给检测系统的单片机供电的电路部分的原理图,交流经过一个变比合适的变压器接给整流桥的两端,整流桥D4将交流7.5V整为直流10V左右,电容作用之一是用来滤波,保证直流电压的平稳,之二是用来储能,保证在缺相、停电后,还有足够的电能供单片机完成保存数据的工作。
稳压芯片7805将直流电压稳定在5V,给各种芯片供电。
图2是三相电源掉电检测的主电路,三相电源如上图所示接成星型,三只光耦用来检测缺相情况,当三相电正常时,三只光耦互差120度交替导通,图中标注的VT端将始终保持低电平,一旦发生缺相情况,VT端将出现高电平,触发单片机的外中断,记录下停电时间。
等VT端恢复低电平,单片机将检测10秒,若10秒钟完全是低电平,则认为已经来电,记录下来电时间。
原边电阻用来给光耦原边限流,二极管用于给负半周电压续流。
图3是PIC单片机系统与时钟芯片DS12887以及液晶显示模块的接口电路的框图。
PIC单片机管脚AD0~AD7的管脚是双向数据端口,同时连着时钟芯片DS12887和液晶的数据线。
RD,CS,ALE,RW是时钟的读写控制线,E1,E2,RW是液晶的读写控制线。
图2 掉电检测电路图3 单片机系统的框图3、 PIC单片机、时钟芯片DS12887以及液晶模块PIC单片机是美国Microship公司的产品,具有很高的性价比,采用类-精简指令集(RISC-like),指令高效容易学习和开发。
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单片机如何表示电压
PIC单片机如何表示电压PIC用十位二进制位的数来表示电压,也就是数值0~1023来表示电压。
那比如现在这个数值是400那这代表多少的电压?这就要根据参考电压来确定了。
比如我们设置正参考电压为3.3V ,当输入的电压为0时,数值就为0。
当输入的电压为3.3V时,数值就是1023. 那如果输入的电压是1.2V代表多少电压。
首先,先算出一个数值代表多少的电压 3.3V除以1023 约等于0.003V .然后,1.2V除以0.003V 等于400. 这就得出了400代表的是1.2V。
见下图我们可以看AN0~AN7.这些都是可以配置成模拟输入的端口。
只有这些引脚才能做为AD转换的端口。
实例讲解:例如:我们看第一张的原理图,从RA0/AN0脚输入个模拟量如果电压大于1.2v则LED亮否则LED灭。
AD的设置步骤:1,设置端口将RA0口设置为输入TRISA =0x01;将RA0口设置为模拟ANSELA = 0x01;2, 配置ADC模块选择ADC的转换时钟。
如何选择转换时钟呢要根据现在的时钟频率进行选择。
可以根据数据手册中的表格进行选择。
我们设置单片机的时钟频率为32MHZ ,选择ADC周期关键不要选择阴影部分,在32MHz 这一列我们随意选择了ADC时钟周期1us,对应的时钟源为Fosc/32.,AD控制寄存器1 ADCON1的Adcs=010注:ADCS代表的意思就是ADCS的0到2位配置参考电压我们这里把正参考电压配置为电源压。
AD控制寄存器1 ADCON1的ADPREF=00;配置左/右对齐AD转换后数值是十位的二进制,我们用单片机却只是八位的,所以PIC单片机,用两个八位的寄存器来存放AD值,ADRESH用来存放高位结果,ADRESL用来存放低位结果。
可是ADRESH和ADRESL加起来是十六啊。
那这十位的数值是怎么放在里面的。
这就靠左右对齐来设置,如果是右对齐低8八位放在ADRESL,剩下的2位放在ADRESH中。
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;//如果液晶没被关闭,则继续关}}有了以上的通用子程序,就可以构造出各种显示程序,如字符。
单片机测量电压的程序
if (RI)
{
RI=0;
Recieve[m]=SBUF;
m++;
if(m==4)
{
unsigned int tempp=(Recieve[1]-48)*100+(Recieve[2]-48)*10+(Recieve[3]-48);
if(Recieve[0]=='r')
{
Shangxian=tempp;
void SendData(unsigned char dat)
{
SBUF = dat; //写数据到UART数据寄存器
while(TI==0);
TI=0;
}
void SendString(char *s)
{
while (*s) //检测字符串结束标志
{
SendData(*s++); //发送当前字符
P21=~P21;
else if(Volut<Xiaxian)
P22=~P22;
else
{
P21=1;P22=1;
}
}
}
/*----------------------------
UART中断服务程序
-----------------------------*/
void Uart() interrupt 4
while(1)
{
if(thflag)
{
thflag=0;
ADC_CONTR|=0X08;//启动转换
while(!(ADC_CONTR&0x10));
ADC_CONTR&=0xE7; //转换结束标志位清零
dataL=ADC_RESL;
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第11章交流电压测量
11.3.2 程序清单
该程序已在模板上调试通过,可作读者的参考。
有关显示部分请读者参考本书相关章节,有关A/D转换的详细设置请参考前面章节。
#include <pic.h>
#include <math.h>
#include <stdio.h>
//该程序用于测电网的交流电压有效值,最后的结果将在4个LED上显示,保留
//1位小数。
//为了保证调试时数据运算的精确性,需要将PICC的double型数据选成32位
union adres
{
int y1;
unsigned char adre[2];
}adresult;//定义一个共用体
bank3 int re[40];//定义存放A/D转换结果的数组,在bank3中
unsigned char k,data;//定义几个通用寄存器
double squ ,squad;//平方寄存器和平方和寄存器,squ又通用为存储其
//它数值
int uo;
bank1 unsigned char s[4];//此数组用于存储需要显示的字符的ASII码
const char table[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0XD8,0x80,0x90};
//不带小数点的显示段码表
const char table0[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};//带小数点的显示段码表
//A/D转换初始化子程序
void adinitial()
{
ADCON0=0x41;//选择A/D通道为RA0,且打开A/D转换器
//在工作状态,使A/D转换时钟为8Tosc ADCON1=0X8E;//转换结果右移,及ADRESH寄存器的高6位为"0"
//把RA0口设置为模拟量输入方式
ADIE=1;//A/D转换中断允许
PEIE=1;//外围中断允许
186
TRISA0=1;//设置RA0为输入方式
}
//spi方式显示初始化子程序
void SPIINIT()
{
PIR1=0;
SSPCON=0x30;
SSPSTAT=0xC0;
//设置SPI的控制方式,允许SSP方式,并且时钟下降沿发送,与"74HC595,当其
//SCLK从低到高跳变时,串行输入寄存器"的特点相对应
TRISC=0xD7;//SDO引脚为输出,SCK引脚为输出
TRISA5=0;//RA5引脚设置为输出,以输出显示锁存信号
}
//系统其它初始化子程序
void i nitial()
{
CCP2IE=0;//禁止CCP中断
SSPIE=0;//禁止SSP中断
CCP2CON=0X0B;//初始化CCP2CON,CCP2为特别事件触发方式
CCPR2H=0X01;
CCPR2L=0XF4;//初始化CCPR2寄存器,设置采样间隔500 μs,
//一个周期内电压采40个点
}
//中断服务程序
void interrupt adint(void)
{
CCP2IF=0;
ADIF=0;//清除中断标志
adresult.adre[0]=ADRESL;
adresult.adre[1]=ADRESH;//读取并存储A/D转换结果,A/D转换的结果
//通过共用体的形式放入了变量y1中
re[k]=adresult.y1;//1次A/D转换的结果存入数组
k++;//数组访问指针加1
}
//SPI传送数据子程序
void SPILED(data)
{
187
SSPBUF=data;//启动发送
do{
;
}while(SSPIF==0);
SSPIF=0;
}
//主程序
main( )
{
adinitial();//A/D转换初始化
SPIINIT();//spi方式显示初始化
initial();//系统其它初始化
while(1){
k=0;//数组访问指针赋初值
TMR1H=0X00 ;
TMR1L=0X00;//定时器1清0
ei();//中断允许
T1CON=0X01;//打开定时器1
while(1){
if(k==40) break;//A/D转换次数达到40,则终止
}
di();//禁止中断
for(k=0;k<40;k++)re[k]=re[k]-0X199;//假设提升电压为2 V,对应十六进制数199H,
//则需在采样值的基础上减去该值
for(k=0,squad=0;k<40;k++) {
uo=re[k];
squ=(double)uo;//强制把采得的数据量转换成双精度数,以便运算
squ=squ*5/1023;//把每点的数据转换成实际数据
squ=squ*squ;//求一点电压的平方
squad=squad+squ;
} //以上求得40点电压的平方和,存于寄存器 squad中squ=squad/40;//求得平均值
squ=sqrt(squ);//开平方,求得最后的电压值
squ=squ*154.054;//通过变压器的变比和分压电阻分配确定该系数
//以上得到了实际电网的电压值
squ=squ*10;//为了保证显示的小数点的精度,先对电压值乘以10
188
uo=(int)squ;//强制把U转换成有符号整型量
sprintf(s,"%4d",uo);//通过sprintf函数把需要显示的电压数据转换成
//ASII码,并存于数组S中
RA5=0;//准备锁存
for(k=0;k<4;k++){
data=s[k];
data=data&0X0F;//通过按位相与的形式把ASII码转换成BCD码
if(k==2) data=table0[data];//因为squ已乘以10,则需在第2位打小数点
else d ata=table[data];// table0存储带小数点的显示段码,
//table存储不带小数点的显示段码
SPILED(data);//发送显示段码
}
for(k=0;k<4;k++) {
data=0xFF;
SPILED(data);//连续发送4个DARK,使显示看起来好看一些,这点与
//该实验板的LED分布结构有关
}
RA5=1;//最后给一个锁存信号,代表显示任务完成
}
}
189。