robin_chen559的个人空间 https://bbs.21ic.com/?1089975 [收藏] [复制] [RSS]

日志

PIC12LF1822 AD串口发送&C51串口接收 LCD1602显示

已有 891 次阅读2013-12-25 12:49 |个人分类:单片机笔记|系统分类:单片机| PIC12LF1822, LCD1602显示

(1) PIC12LF1822做上位机,进行AD采样,并把AD采样结果通过串口发出
(2) 51单片机做为下位机,将串口接收到的信息进行处理,并将之显示在lcd1602上
(3)上位机程序:
/************************************************************
项目名称:1822AD_串口显示
要求:1822AD_串口显示,左对齐取高八位
设计:robin_chen559
日期:2013.12.15
备注:
************************************************************/
#include              //包含头文件pic12lf1822.h


#define LED_G  RA0             //RA0为LED_G口
#define uchar unsigned char
#define uint  unsigned int

uint AD_VAL_AVR = 0;              //AD处理结果  

//子程序声明

void Init_star(void);       //系统初始化
void Init_UART(void);       //串口初始化
void Delay_MS(uint MS);     //延迟子程序
void Init_AD(void);         //AD初始化
void AD_AVR(void);          //AD结果处理

//子程序
void Init_star(void)        //系统初始化子程序
{
   OSCCON = 0b01101010;        //4M系统时钟
   APFCON = 0b10000100;        //端口复用定义RA5/4 RD TX,RA2 CPP
   TRISA  = 0b00101010;        //A口输入输出设置,RA5/1/3输入,RA4/0/2输出
   ANSELA = 0b00001110;        //RA1/RA2/RA3拟输入_AD,其他全部是数字输入
}

void Init_UART(void)
{
INTCON  = 0b11000000;         //开总中断GIE,外设中断PEIE
TXIE    = 0;                  //发送中断
ADIE    = 0;                  //禁止AD中断
TXSTA   = 0b00100110;         //串口配置字
RCSTA   = 0b10010000;         //接受寄存器配置P295
BAUDCON = 0b01001000;         //16位波特率计数器,固定波特率
SPBRGH  = 0b00000000;         //011,16位异步,9600波特率,查表103
SPBRGL  = 0b01100111;
}

void Init_AD(void)
{
ADCON0 = 0B00000101;          //AD使能,选AN1
ADCON1 = 0B00110011;          //AD结果左对齐,内rc,2V内部考电压
FVRCON = 0b11000010;          //2v内部参考电压配置
}

void AD_AVR(void)                 //AD结果处理
{
uchar n;
uchar m;
AD_VAL_AVR = 0;

   ADGO = 1;                     //开始AD转换
   for(n=0;n<5;n++)              //延时20uS待电平稳定
   {NOP();}
   while(ADGO == 1);             //等待AD转换完成
   ADIF = 0;                     //清除转换完成标志
   AD_VAL_AVR =ADRESH;           //AD结果5次自加
  
  
  //AD_VAL_AVR=AD_VAL_AVR/10;      //AD结果10次求均值
  // TXIE = 1;                     //串口发送中断使能
}

void Delay_MS(uint MS)         //延时函数
{
  uint i;
  uchar j;

   for(i=0;i<MS;i++)       
      for(j=115;j>0;j--);         
}

/*****
void interrupt ISR(void)       //中断子程序无需声明
{
if(TXIE == 1)
{      
   TXREG = AD_VAL_AVR  ;        //Uart_Data
   while(TRMT == 0);            //串口发送中,等待
   TXIE   = 0;                  //防止串口发送中断一直申请
}
}
*****/

void main (void)             //主程序
{
Init_star();                //开机初始化
Init_UART();                //中断初始化
Init_AD();                  //AD初始化

while(1)
{
    AD_AVR();
    TXREG = AD_VAL_AVR ;           //AD_VAL_AVR
    while(TRMT == 1);
    LED_G = 0;
    Delay_MS(500);
    LED_G = 1;
    Delay_MS(500);
   
}
}   
(4) 下位机程序:
/******************************************************************
1.项目:STC12c5410 ad采样通过串口发给51单片机并在LCD上显示
2.功能:
  2.1:串口接收数据
  2.2:数据在1602上显示电压数据
  2.3:数据通过串口回发
3.设计:robin_chen559
4.日期:2013.12.25
备注:C51,11.0592M晶振

******************************************************************/
#include            //包含头文件

#define uint unsigned int    //预定义
#define uchar unsigned char

sbit rs=P3^5;        //1602的数据/指令选择控制线
sbit rw=P3^6;        //1602的读写控制线
sbit en=P3^7;        //1602的使能控制线

uchar shi,ge,d1,d2;  //定义电压十位个位点位
uchar code table[] = {"0123456789abcdef"}; //定义显示字符串

/****************函数声明*********************/
void Init_UART(void);                    //串口初始化
void lcd_wcom(uchar com);                                //1602写指令
void lcd_wdat(uchar dat);                                //1602显示数据
void lcd_init();                                                //1602初始化
void delay(uint n);                                                //延时子程序
void putchar(unsigned char data1);                //串口发送数据
void putstring(unsigned char *dat);                //串口发送字符串
void LCD_Display(void);                  //LCD显示子程序

/***************子程序************************/

//串口初始化子程序
void Init_UART(void)
{
SCON = 0x50;           //串口方式1 ,允许接收
TMOD = 0x20;           //T1工作于方式2
PCON = 0x00;           //波特率不倍增
TL1  = 0xfd;           //波特率设置
TH1  = 0xfd;           
EA   = 1;              //开总中断
ES   = 1;              //开串口接收中断
//TI = 0;
TR1 = 1;               //定时器开启
}

//串口接收子程序
void revdata(void) interrupt 4
{
  uint temp;
  if(RI == 0) return;          //如果没有接收中断标志,返回
  ES = 0;                      //关闭串口中断
  RI = 0;                      //清串行中断标志位
  temp = SBUF;                 //接收缓冲器中的字符
  putchar(temp);               //将接收的字符发送出去
  ES = 1;                      //开启串口中断
  shi = 0;
  ge = 2*temp/256;                                                //计算个位
  d1 = (20*temp/256-10*ge);                                //计算小数点后1位
  d2 = (200*temp/256-100*ge-10*d1);                //计算小数点后2位
}  

//字符发送函数
void putchar(unsigned char data1)  
{
  SBUF = data1;               //将待发送的字符送入发送缓冲器
  while(TI == 0);             //等待发送完成
  TI = 0;                     //发送中断标志请0
}

//字符串发送函数
void putstring(unsigned char *dat)
{
  while(*dat != '\0')           //判断字符串是否发送完毕
{
  putchar(*dat);                //发送单个字符
  dat++;                        //字符地址加1,指向先下一个字符
  delay(5);
}
}

//毫秒级延时函数
void delay(uint n)              //延时函数                       
{
    uint x,y;  
    for(x=n;x>0;x--)
        for(y=110;y>0;y--);
}

//1602写命令子程序
void lcd_wcom(uchar com)                 
{
    rs=0;            //选择指令寄存器
    rw=0;            //选择写
    P2=com;          //把命令字送入P2
    delay(5);        //延时一小会儿,让1602准备接收数据
    en=1;            //使能线电平变化,命令送入1602的8位数据口
    en=0;
}

//1602初始化子程序
void lcd_init()                  
{
    lcd_wcom(0x38);          //8位数据,双列,5*7字形  38     
    lcd_wcom(0x0c);          //开启显示屏,关光标,光标不闪烁  0C
    lcd_wcom(0x06);          //显示地址递增,即写一个数据后,显示位置右移一位
    lcd_wcom(0x01);          //清屏
}
//1602写数据子程序   
void lcd_wdat(uchar dat)           
{
    rs=1;               //选择数据寄存器
    rw=0;               //选择写
    P2=dat;             //把要显示的数据送入P2
    delay(1);           //延时一小会儿,让1602准备接收数据
    en=1;               //使能线电平变化,数据送入1602的8位数据口
        delay(1);      
    en=0;
}

//1602显示子程序
void LCD_Display(void)
{
  //LCD第一行显示
  lcd_wcom(0x80+0x01);
  lcd_wdat('R');
  lcd_wcom(0x80+0x02);
  lcd_wdat('o');
  lcd_wcom(0x80+0x03);
  lcd_wdat('b');
  lcd_wcom(0x80+0x04);
  lcd_wdat('i');
  lcd_wcom(0x80+0x05);
  lcd_wdat('n');
  lcd_wcom(0x80+0x06);
  lcd_wdat('_');
  lcd_wcom(0x80+0x07);
  lcd_wdat('C');
  lcd_wcom(0x80+0x08);
  lcd_wdat('h');
  lcd_wcom(0x80+0x09);
  lcd_wdat('e');
  lcd_wcom(0x80+0x0a);
  lcd_wdat('n');
  lcd_wcom(0x80+0x0b);
  lcd_wdat('5');
  lcd_wcom(0x80+0x0c);
  lcd_wdat('5');
  lcd_wcom(0x80+0x0d);
  lcd_wdat('9');
  
  //LCD第二行显示

  lcd_wcom(0x80+0x42);
  lcd_wdat('V');
  lcd_wcom(0x80+0x43);
  lcd_wdat('o');
  lcd_wcom(0x80+0x44);
  lcd_wdat('l');
  lcd_wcom(0x80+0x45);
  lcd_wdat(':');
  lcd_wcom(0x80+0x46);
  lcd_wdat(table[shi]);
  lcd_wcom(0x80+0x47);
  lcd_wdat(table[ge]);
  lcd_wcom(0x80+0x48);
  lcd_wdat('.');
  lcd_wcom(0x80+0x49);
  lcd_wdat(table[d1]);
  lcd_wcom(0x80+0x4a);
  lcd_wdat(table[d2]);
  lcd_wcom(0x80+0x4b);
  lcd_wdat('v');
}

//主函数
void main(void)
{
Init_UART();                //串口初始化
lcd_init();             //液晶初始化

while(1)
{  
  LCD_Display();        
}
}
(5) 原文件:MPlab8.70/keeil uv4 /proteus7.10

路过

鸡蛋

鲜花

握手

雷人

发表评论 评论 (1 个评论)

回复 robin_chen559 2013-12-25 12:52
单片机分块学习,基本过了一遍,以后边做项目边下水磨功夫了