基于PIC16F873A的照度测量C语言代码。
可以使用Labview以RS232接口和PC通信,并获取实时数据
单片机源程序如下:
- #include <pic.h> //调用PIC16F87XA单片机的头文件
- __CONFIG(HS&WDTDIS&LVPDIS);
- #define U5A RC0 //4位数码管单元的U5(74HC138)的A脚接在RB0口上
- #define U5B RC1 //4位数码管单元的U5(74HC138)的B脚接在RB1口上
- #define U5C RC2 //4位数码管单元的U5(74HC138)的C脚接在RB2口上
- unsigned char temp1;
- unsigned char temp2;
- const unsigned char LED[28]=
- {
- 0x3F,/*0*/
- 0x06,/*1*/
- 0x5B,/*2*/
- 0x4F,/*3*/
- 0x66,/*4*/
- 0x6D,/*5*/
- 0x7D,/*6*/
- 0x07,/*7*/
- 0x7F,/*8*/
- 0x6F,/*9*/
- 0x77,/*A*/
- 0x7C,/*b*/
- 0x39,/*C*/
- 0x58,/*c*/
- 0x5E,/*d*/
- 0x79,/*E*/
- 0x71,/*F*/
- 0x76,/*H*/
- 0x74,/*h*/
- 0x38,/*L*/
- 0x54,/*n*/
- 0x37,/*N*/
- 0x5C,/*o*/
- 0x73,/*P*/
- 0x50,/*r*/
- 0x78,/*t*/
- 0x3E,/*U*/
- 0x40,/*-*/
- };
- //---------------------------------------
- //A/D转换用寄存器设置
- unsigned int ADbuf; //设置16位的unsigend int型寄存器用来暂存转换结果
- unsigned int adcbuf[16];
- void main(void) //主函数,单片机开机后就是从这个函数开始运行
- {
- unsigned char buf;
- unsigned char USARTbuf;
- unsigned char c=0; //定义一个char型变量,做延时用
- unsigned char e=0; //定义一个char型变量,做延时用
- unsigned char i;
- unsigned char b;
- unsigned char d=0; //定义一个char型变量,控制显示位置
- TRISA=0B11111111; //初始化RA5-RA0的输出方向
- TRISC=0B11111000; //RB0-3设置为输出
- TRISB=0B00000000; //RD设置为输出
- PORTA=0B00000000; //初始化RA5-RA0数值
- PORTB=0B00000000; //初始化RB7-RB0的数值
- PORTB=0B00000000; //初始化RD7-RD0的数值
- //****A/D模块初始化****
- //ADCON1=0B10001110; //RA0为A/D输入口;ADFM=1,转换后数据右移,ADRESL为低8位数据
- ADCON1=0B10001111; //RA0为A/D输入口;ADFM=1,转换后数据右移,ADRESL为低8位数据
- //设置RA2=Vref-(GND),RA3=Vref+
- /*
- 详细分析该设置:
- ADFM=1,结果右移,ADRESH寄存器的高六位读作“0”
- bit6~4未用,以0设置
- bit3~0 RA0作为模拟信号输入端,其余引脚(RA1~7)都是数字信号输入端
- */
- ADIE=0; //禁止A/D中断
- //*********************
- //*****USART串口初始化*****
- SPBRG=25; //设置波特率为9600,误差0.16%
- BRGH=1; //设置高速波特率
- SYNC=0; //SYNC=0为异步模式,SYNC=1为同步模式
- SPEN=1; //允许串口操作
- CREN=1; //CREN=0禁止连续接收,CREN=1允许连续接收
- TXIE=0; //禁止发送中断
- RCIE=0; //禁止接收中断
- TX9=0; //TX9=0为8位发送,TX9=1为9位发送
- RX9=0; //RX9=0为8位接收,RX9=1为9位接收
- TXEN=1; //TXEN=0为禁止发送,TXEN=1为允许发送
-
- while(1) //死循环,单片机初始化后,将一直运行这1个死循环
- {
- for(i=0;i<16;i++) //连续采样16次,然后取平均数
- {
- //***启动一次A/D转换***
- ADCON0=0B00000001; //选择AN0通道准备进行A/D转换,启动A/D模块
- /*
- 详细分析该设置:
- ADCS1:ADCS0=00,fosc/2;4MHz/2=2MHz?
- CHS2:CHS0=000,选择模拟通道RA0
- GO/DONE=0,未进行A/D转换,A/D转换完成后该位自动清零
- bit1=0,该位未用
- ADON=1,打开A/D转换器的工作状态
- */
- asm("NOP"); //略做延时
- asm("NOP"); //略做延时
- asm("NOP"); //略做延时
- asm("NOP"); //略做延时
- ADGO=1; //开始进行A/D转换
- while(ADGO) continue; //等待A/D转换结束
- adcbuf[i]=ADRESH*256+ADRESL;
-
- //*********************
- }
- ADbuf=0;
- for(i=0;i<16;i++)
- {
- ADbuf+=adcbuf[i]; //把连续转换了16次的AD值加在一起
- }
- ADbuf=ADbuf/16; //除以16,算16次采样的平均值
-
- ADbuf=(int)(((float)ADbuf/1023)*1000); //将0-1023换算成电压值000-1000
- temp1=ADbuf/100;
- temp2=ADbuf%100;
- if(ADbuf<999)
- {
- PORTB=0; //关一次显示,以免显示出鬼影
- if(++d>3) d=0; //先将d加1,然后判断是否大于3,大于3归零
- if(d==0) //如果d=0,显示千位
- {
- U5A=0; //U5A=0,U5B=0,U5C=0,选通数码管的千位进行显示
- U5B=0; //U5A=0,U5B=0,U5C=0,选通数码管的千位进行显示
- U5C=0; //U5A=0,U5B=0,U5C=0,选通数码管的千位进行显示
- PORTB=LED[(ADbuf%10000)/1000]; //将要显示的f的千位提取出来查表后送显示
- }
- else if(d==1) //如果d=1,显示百位
- {
- U5A=1; //U5A=1,U5B=0,U5C=0,选通数码管的百位进行显示
- U5B=0; //U5A=1,U5B=0,U5C=0,选通数码管的百位进行显示
- U5C=0; //U5A=1,U5B=0,U5C=0,选通数码管的百位进行显示
- PORTB=LED[(ADbuf%1000)/100]; //将要显示的f的百位提取出来查表后送显示
- }
- else if(d==2) //如果d=2,显示十位
- {
- U5A=0; //U5A=0,U5B=1,U5C=0,选通数码管的十位进行显示
- U5B=1; //U5A=0,U5B=1,U5C=0,选通数码管的十位进行显示
- U5C=0; //U5A=0,U5B=1,U5C=0,选通数码管的十位进行显示
- PORTB=LED[(ADbuf%100)/10]; //将要显示的f的十位提取出来查表后送显示
- }
- else if(d==3) //如果d=3,显示个位
- {
- U5A=1; //U5A=1,U5B=1,U5C=0,选通数码管的个位进行显示
- U5B=1; //U5A=1,U5B=1,U5C=0,选通数码管的个位进行显示
- U5C=0; //U5A=1,U5B=1,U5C=0,选通数码管的个位进行显示
- PORTB=LED[ADbuf%10]; //将要显示的f的个位提取出来查表后送显示
- }
- }
- if(ADbuf>999)
- {
- PORTB=0; //关一次显示,以免显示出鬼影
- if(++d>3) d=0; //先将d加1,然后判断是否大于3,大于3归零
- if(d==0) //如果d=0,显示千位
- {
- U5A=0; //U5A=0,U5B=0,U5C=0,选通数码管的千位进行显示
- U5B=0; //U5A=0,U5B=0,U5C=0,选通数码管的千位进行显示
- U5C=0; //U5A=0,U5B=0,U5C=0,选通数码管的千位进行显示
- PORTB=LED[15]; //将要显示的f的千位提取出来查表后送显示
- }
- else if(d==1) //如果d=1,显示百位
- {
- U5A=1; //U5A=1,U5B=0,U5C=0,选通数码管的百位进行显示
- U5B=0; //U5A=1,U5B=0,U5C=0,选通数码管的百位进行显示
- U5C=0; //U5A=1,U5B=0,U5C=0,选通数码管的百位进行显示
- PORTB=LED[15]; //将要显示的f的百位提取出来查表后送显示
- }
- else if(d==2) //如果d=2,显示十位
- {
- U5A=0; //U5A=0,U5B=1,U5C=0,选通数码管的十位进行显示
- U5B=1; //U5A=0,U5B=1,U5C=0,选通数码管的十位进行显示
- U5C=0; //U5A=0,U5B=1,U5C=0,选通数码管的十位进行显示
- PORTB=LED[0]; //将要显示的f的十位提取出来查表后送显示
- }
- else if(d==3) //如果d=3,显示个位
- {
- U5A=1; //U5A=1,U5B=1,U5C=0,选通数码管的个位进行显示
- U5B=1; //U5A=1,U5B=1,U5C=0,选通数码管的个位进行显示
- U5C=0; //U5A=1,U5B=1,U5C=0,选通数码管的个位进行显示
- PORTB=LED[10]; //将要显示的f的个位提取出来查表后送显示
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
illuminometer.rar
(176.22 KB, 下载次数: 45)
|