標題: PIC16F877A單片機做個電壓電流表 [打印本頁]

作者: bg7nr    時間: 2017-1-5 13:59
標題: PIC16F877A單片機做個電壓電流表
手頭上有PIC16F877A,LCD1602,想DIY個直流電壓電流顯示器,菜鳥一個,手上有LED顯示的電壓表程序,哪位有1602顯示的程序,分享下行嗎
作者: bg7nr    時間: 2017-1-5 14:19
//////////////////////////////////////////////////
//  Author     :   Toby
//  Date       :   2009/03/08
//  Function   :   數字電壓表程序,用數字濾波的方式,并在LCD 1602上顯示
//  MCU        :   PIC16F877A
//  C Compiler :   PICC 8.05
//  IDE        :   MPLAB IDE v8.10               
/////////////////////////////////////////////////

__CONFIG(0x1832);        
//芯片配置字,看門狗關,上電延時開,掉電檢測關,低壓編程關,加密,4M晶體HS振蕩

union  adres                                                            //定義一個共用體,用于存放10位A/D轉換的結果
{int  y1;
unsigned  char  adre[2];
}adresult;

unsigned int ADC=0;

void adinitial_voltage(void);// RA0為AD輸入

const char TABLE[]={'0','1','2','3','4','5','6','7','8','9'};  //定義常數0-9的數據表格
const char data[4]={'0','0','0','0'};
#define rs RA1
#define rw RA2
#define e  RA3

const char voltage[ ]={'V','O','L','T','A','G','E','='};

unsigned char ge=0,shi=0,bai=0,qian=0;   //定義6個臨時變量
void init();                   //申明I/O口初始化函數
void lcd_init();               //申明LCD初始化函數
void lcd_dis();
void write_voltage();            
void write(char x);            //申明顯示1字節(jié)數據函數
void lcd_enable();             //申明LCD顯示設置函數
void delay();                  //申明延時函數

//---------------------------------------
//主函數
void main()
{     
    unsigned char a;
    init();                //調用I/O口初始化函數
    while(1)
      {
   
         adinitial_voltage();
         lcd_init();    //調用LCD初始化函數
         for(a=10;a>=1;a--)
          {   
            PORTD=0X80;               
            lcd_enable();

            write_voltage();

            PORTD=TABLE[qian];                   //待顯示數據送PORTD口
            lcd_dis();
           
            PORTD='.';                          //待顯示數據送PORTD口
            lcd_dis();

            PORTD=TABLE[bai];                   //待顯示數據送PORTD口
            lcd_dis();
      
            PORTD=TABLE[shi];                   //待顯示數據送PORTD口
            lcd_dis();
      
            PORTD=TABLE[ge];                   //待顯示數據送PORTD口
            lcd_dis();

      }         
  
      }
}

//---------------------------------------
//I/O口初始化函數
void init()
{
    ADCON1=0X0;                //設置A口為普通I/O口
    TRISA=0B00000001;          //設置A口為輸出
    TRISD=0X00;                //設置D口為輸出
}

//---------------------------------------
//LCD初始化函數
void lcd_init()
{
    PORTD=0X1;                 //清除顯示
    lcd_enable();
    PORTD=0X38;                //8位2行5*7點陣
    lcd_enable();
    PORTD=0X0c;                //顯示開,光標開,閃爍
    lcd_enable();
    PORTD=0X06;                //文字不動,光標右移
    lcd_enable();
   
}


//--------------------------------------
//顯示公司tel函數
void write_voltage()
{
    unsigned char  i;
    for(i=0;i<=7;i++)       //一共顯示16字節(jié)數據
       {
         write(voltage[i]);       //查表獲取數據并調用寫一個字節(jié)數據函數送LCD顯示
       }
}
  
//--------------------------------------
//寫一個字節(jié)數據函數  
void write(char x)
{
  PORTD=x;                   //待顯示數據送PORTD口
  lcd_dis();
}

//--------------------------------------
//LCD顯示設置函數
void lcd_enable()
{
   rs=0;                     //該字節(jié)數據為命令,而不是數據     RS=1數據RS=0命令
   rw=0;                     //此次操作為寫,而不是讀           RW=1讀RW=0寫
   e=0;                      //拉低使能信號
   delay();                  //保持使能信號為低一段時間
   e=1;                      //拉高使能信號,建立LCD操作所需要的上升沿
}
void lcd_dis()
{
   rs=1;                     //該字節(jié)數據為命令,而不是數據     RS=1數據RS=0命令
   rw=0;                     //此次操作為寫,而不是讀           RW=1讀RW=0寫
   e=0;                      //拉低使能信號
   delay();                  //保持使能信號為低一段時間
   e=1;                      //拉高使能信號,建立LCD操作所需要的上升沿
}
  
//延時函數
void delay()
{
   int i;
   for(i=0;i<50;i++);
}


void adinitial_voltage(void)// RA0為AD輸入
{   
         unsigned int AD_data[5]={0,0,0,0,0};
         for(j=0;j<=4;++j)
           {
             ADCON0=0B01000001;     //A/D 轉換器模塊工作;但AD轉換不進行;FOSC/8
             ADCON1=0B11101110;     //ADRESH 寄存器的高6 位讀為0;6位與7位須置1
             ADGO=1;
             while(ADGO);             //等AD轉換完成
             adresult.adre[0]=ADRESL;
             adresult.adre[1]=ADRESH;  //讀取并存儲A/D轉換結果
             AD_data[j]=adresult.y1;
            
          }
             for(j=0;j<=4;++j)
               if(AD_data[j]>AD_data[j+1])
                {temp=AD_data[j];AD_data[j]=AD_data[j+1];AD_data[j+1]=temp;}//找出最大的數,

                    for(j=0;j<=3;++j)
                      if(AD_data[j]<AD_data[j+1])
                         {temp=AD_data[j];AD_data[j]=AD_data[j+1];AD_data[j+1]=temp;} //找出最小數

                            ADC=((AD_data[0]+AD_data[1]+AD_data[2])/3)/213.20008328128253175098896523006*1000;//中間數作平均
        
                                 qian=ADC/1000;
                                  bai=ADC%1000/100;            
                                   shi=ADC%100/10;            
                                     ge=ADC%10;               
}

作者: bg7nr    時間: 2017-1-5 14:26
網上下的,編譯不了
作者: z56155909    時間: 2017-1-5 15:27
幫忙頂,,,,,,,,




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1