PIC单片机(PIC16F873)小项目六(源程序)
/*;**文 件 名: xxxxxx板程序;**创 建 人: Hbx;**最后修改日期: 2009年11月10日;**描 述: xxxxx *///头文件#include<pic.h>#include<pic168xa.h> //全局变量定义 bank1 unsigned char check;bank1 int full_eeprom,empty_eeprom,calibration,advalue;bank1 int full_eeprom2,empty_eeprom2,calibration2,jz35; char bank1 shiwei,gewei,fenwei,biaozhi; float bank1 num1,num2;int bank1 k,t;unsigned char i;//函数声明void Initialization();void sounddelay0(int delay_count);void sound200ms(unsigned char k);void led() ;void led_empty();void led_full();void led_shan();void ledflah (int k );int ad1();int ad12();int ad2();void spi_out(int x);int display(int x) ;void show (int ge,int fen ,int shifen) ;int deal( int n);int deal2(int n);float conversion(int vin,int vin_min,int vin_max,int alignment,float a,float b);void pwm (int k);void compares (float y ,int b);void button();void pwm2 (); __CONFIG(0x1832);//显示查表 bank1 const char TABLE[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0X82,0XF8,0X80,0X90};//--------------------------------------------------//-------------------------------------------显示子函数---------------------------------//--------------------------------------------------void interrupt vision(void){ if(T0IF) { unsigned char h; T0IF=0; TMR0=250; i++; if(i>2) { i=0; } RC4=RB5=RB0=0; if(i==0) { spi_out(TABLE[shiwei]) ; if(shiwei>0) { RC4=1; } } if(i==1) { spi_out(TABLE[gewei]); RB5=1; } if(i==2) { spi_out(TABLE[fenwei]); RB0=1; } } }//--------------------------------------------------//--------------------------------------------主函数------------------------------------//-------------------------------------------------void main() { int r; //定义变量 Initialization(); //系统初始化设置 full_eeprom=eeprom_read (0x01)*100+eeprom_read (0x02); //读EEPROM中的xx值 empty_eeprom=eeprom_read (0x03)*100+eeprom_read (0x04); //读EEPROM中的xx值 calibration=eeprom_read (0x05)*100+eeprom_read (0x06); //读EEPROM中的xx值 sound200ms(1); //调用发声函数 led(); //调用LED函数 GIE=1; //开全局中断 TMR0IE=1; //开定时器中断 while(1){ button(); if(check==1) //调用按键扫描函数 { full_eeprom=eeprom_read (0x01)*100+eeprom_read (0x02); //若有自学习,读EEPROM中的xx值 empty_eeprom=eeprom_read (0x03)*100+eeprom_read (0x04); //若有自学习,读EEPROM中的xx值 calibration=eeprom_read (0x05)*100+eeprom_read (0x06); //若有校准自学习,读EEPROM中的xx值 check=0; } ledflah(ad1()); //调用LED灯闪动函数 k=ad1(); if((k>empty_eeprom)||(k<1)) { k=empty_eeprom; } if(empty_eeprom>=full_eeprom) { num1=empty_eeprom-full_eeprom; num2=empty_eeprom-k; num1=num2/num1; t=num1*100; shiwei=t/100; gewei=(t%100)/10; fenwei=(t%100)%10; } else { shiwei=5; gewei=5; fenwei=5; } r=conversion(ad1(),full_eeprom,empty_eeprom,calibration,3.50,3.01); //0.5-3.5V电压模式输出 pwm(r); //调用PWM函数 }} //%%%%%%%%%%%%%%%%%%以下是各子函数定义%%%%%%%%%%%%%%%%%%%%%//----------------------------------------------//-------------------------------------------显示子函数----------------------------//----------------------------------------------/** 函数名称: display;** 功能描述: 此函数用于实现数码管显示输入值。;** 输 入: x;** 输 出 : 无;** 全局变量: 无;** 调用模块: 无*///spi输出函数 void spi_out(int x) { SSPBUF=x; //SPI输出X }//----------------------------------------------//---------------------------------------数据转换子函数-----------------------------//----------------------------------------------/**********************************************************************************;** 函数名称: conversion;** 功能描述: 此函数用于实现输入到输出的转换,实现输出电压0.5V——3.5V或则0V-10V。;** 输 入: vin, vin_min, vin_max, alignment, a, b;** 输 出 : vout;** 全局变量: 无;** 调用模块: 无*/ float conversion(int vin,int vin_min,int vin_max,int alignment,float a,float b) { int kai20,kai95,kai110; float c1,c2,c3,vout; //模拟量输出 if(vin>vin_max) { vin=vin_max; } if(vin<vin_min) { vin=vin_min; } //c3=alignment; //c3=c3/1854; c1=vin-vin_min; //vin是输入值,vin_min是xx自学习值,vin_max是xx自学习值 c2=vin_max-vin_min; vout=a-b*c1/c2; //依据公式(vin-vin_min)/(vin_max-vin_min)=(vout-3.5)/(0.5-3.5) //vout=vout*51; vout=vout*256; //vout=vout*c3; vout=vout/4.99; return vout; }//--------------------------------------------------//----------------------------------------------pwm子函数-------------------------------//-------------------------------------------------/** 函数名称: PWM;** 功能描述: 此函数用于实现pwm波形输出。;** 输 入: v;** 输 出 : 无;** 全局变量: 无;** 调用模块: 无*///PWM输出函数 void pwm (int v) { CCPR1L=v; TMR2ON=0x01; //PWM波形输出 sounddelay0(500); //延时 } //--------------------------------------------------//-----------------------------------------------按键子函数-----------------------------//--------------------------------------------------/** 函数名称: compares;** 功能描述: 此函数用于扫描按键,并作出对应处理。;** 输 入: 无;** 输 出 : 无;** 全局变量: check;** 调用模块: eeprom_write(),eeprom_read(), */void button() { int back1; if(RB3==0) sounddelay0(30); if(RB3==0) { led(); if(RB2==0) sounddelay0(40); //B3,B2同时按下进行xx自学习 if(RB2==0) { back1=ad1(); eeprom_write(0x01,back1/100); eeprom_write(0x02,back1%100); ound200ms(2); check=1; } if(RB1==0) //B1,B3同时按下进行xx自学习 sounddelay0(40); if(RB1==0) { back1=ad1(); eeprom_write(0x03,back1/100); eeprom_write(0x04,back1%100); sound200ms(2); check=1; } if(RB4==0) //xx自学习 sounddelay0(40); if(RB4==0) { back1=ad1(); eeprom_write(0x05,back1/100); eeprom_write(0x06,back1%100); sound200ms(2); check=1; }} } //--------------------------------------------------//---------------------------------------系统初始化函数--------------------------------//--------------------------------------------------//此函数实现系统初始化/** 函数名称: Initialization;** 功能描述: 此函数用于初始化系统。;** 输 入: 无;** 输 出 : 无;** 全局变量: 无;** 调用模块: 无*/void Initialization(){ //io口初始化设置,1为输入。 TRISC=0X00; //RC0为输入,其它为输出 TRISB=0X9E; //RB0,RB5,RB6为输出,其它为为输入 TRISA|=0X03; //RA0,RA1,RA3为输入,其它为输出。 //ad初始化设置 //OPTION_REG=0X87; TMR0=0Xa0; //ADCON1=0X84; //转换结果左对齐,RA0做模拟输入口,其它做普通I/O ADCON1=0X85; //RA3为外部基准,RA2为数字,RA1,RA0为模拟。 // ADCON0=0X41; //系统时钟Fosc/8,选择RA0通道,允许ADC工作 //spi初始化设置 SSPSTAT=0x00; SSPCON=0x30; //pwm初始化设置 PR2=0xff; //设置PWM周期 CCP1CON=0x0c; T2CON=0x55; //ccp2初始化设置 CCP2CON=0x0c; //button初始化设置 OPTION=0; //定时器初始化设置 //4M的晶体 T=(256-初值)*(4/f)* 分频比 PSA=0; //128分频后 PS2=1; PS1=1; PS0=0; T0IF=0; //清除TMR0的中断标志 T0IE=1;//TMR0中断允许 TMR0=255; //定时1ms T0CS=0;//TMR0工作于定时器方式 } //---------------------------------------------------//----------------------------------------延时子函数------------------------------------//---------------------------------------------------//此函数实现系统初始化/** 函数名称: sounddelay0;** 功能描述: 此函数用于延时。;** 输 入: delay_count;** 输 出 : 无;** 全局变量: 无;** 调用模块: 无*/void sounddelay0(int delay_count){ int i; //定义循环变量 for(i=delay_count;i>0;i--); //根据频率函数输入值决定延时时间}//---------------------------------------------------//-----------------------------------------喇叭子函数------------------------------------//--------------------------------------------------/** 函数名称: sound200ms;** 功能描述: 此函数用于喇叭发声,发声次数可以自定义。;** 输 入: k;** 输 出 : 无;** 全局变量: 无;** 调用模块: 无*/void sound200ms(unsigned char k ){ unsigned char j; for(j=k;j>0;j--) //每个声音循环K次 { RC0=1; //输出声音 sounddelay0(5000); //延长一段时间 RC0=0; //关闭声音 sounddelay0(2000); //延长一段时间 }}//----------------------------------------------------//------------------------------------------LED子函数--------------------------------------//----------------------------------------------------/** 函数名称: led;** 功能描述: 此函数用于喇叭发声,发声次数可以自定义。;** 输 入: k;** 输 出 : 无;** 全局变量: 无;** 调用模块: 无*/void led() //LED子程序 { unsigned char t; for(t=4;t>0;t--) //循环4次 { PORTC=0x40; //点亮LED1 sounddelay0(4000); PORTC=0x80; //点亮LED2 sounddelay0(4000); } }//---------------------------------------------------//---------------------------------------LEDflash子函数----------------------------------//----------------------------------------------------/** 函数名称: ledflah;** 功能描述: 此函数用于实现LED灯闪动功能,当输入值小于1V时,向下灯常亮,当输入值大于2.2V时,向上灯常亮。;** 输 入: k;** 输 出 : 无;** 全局变量: 无;** 调用模块: 无*/ //ledflash子函数 void ledflah (int k ) { unsigned char t; if (k<=1450&k>100) //当输入值小于1V时,过近灯常亮 { PORTC=0x80; sounddelay0(1000); } if((k>=3300)||(k<2)) //当输入值大于2.2V时,过远灯常亮 { PORTC=0x40; sounddelay0(500); } if(k>1450&k<3300) //当输入值在1V与2.2V之间时,过远灯闪动 { for(t=4;t>0;t--) { PORTC=0x40; //点亮LED1 sounddelay0(3000); PORTC=0x00; sounddelay0(3000); //点亮LED2 } } }//------------------------------------------------------//-------------------------------------AD子函数----------------------------------------------//-------------------------------------------------------/** 函数名称: ad1;** 功能描述: 此函数实现AD转换。;** 输 入: 无;** 输 出 : result;** 全局变量: 无;** 调用模块: 无*/ int ad1() { int result=0x00,m=0x00; //定义转换结果寄存器 unsigned char i; //定义循环次数控制寄存器 for(i=16;i>0;i--) //求5次转换结果的平均值 { ADCON0=0X01; //系统时钟Fosc/8,选择RA0通道,允许ADC工作 sounddelay0(100); //保证采样延时 ADGO=0x01; //开启转换过程 while(ADGO); //等待转换完成 m=ADRESH*256+ADRESL; result+=m; //累计转换结果 } result=result/4; //求5次结果的平均值 return result; }//-------------------------------------------------------//------------------------------把AD转换值转换成十进制数------------------------------------//-------------------------------------------------------//此函数用于实现把AD转换值转换成十进制数,以便后面数据运算,比较 int deal(int n) { float ge1,fen1,shifen1,mi1,cun1,baifenwei1; //定义4个临时变量 int vout1; mi1=n*2.70; ge1=mi1/0x400; //求显示的个位 vout1=ge1*1000; return vout1; }