×
嵌入式 > 技术百科 > 详情

MSP430之ADC12之1602显示

发布时间:2020-06-20 发布时间:
|
#include
/*两路数据采集,其中一路很稳定,跳动一两个字,但是另一路跳动就很大了,
我的处理方法是:1 是将多余的通道都接上,采集后排序取中间的或中间
的几个相加再平均,适用于变化较大的输入信号。2 是适用于比较平稳的
输入信号,可4次、8次、16次、32次、64次循环存储平均。这样比较稳定多了。
本程序就是使用了32次循环存储平均*/
typedef unsigned char uchar;
typedef unsigned int  uint;
/**************宏定义***************/
#define DataDir     P4DIR
#define DataPort    P4OUT    
#define Busy     0x80
#define CtrlDir     P3DIR
#define CLR_RS P3OUT&=~BIT0;    //RS = P3.0 
#define SET_RS P3OUT|=BIT0; 
#define CLR_RW P3OUT&=~BIT1; //RW = P3.1
#define SET_RW P3OUT|=BIT1; 
#define CLR_EN P3OUT&=~BIT2; //EN = P3.2 
#define SET_EN P3OUT|=BIT2; 
 
static uint results[32];    //保存ADC转换结果的数组 
void Trans_val(uint dat);
/*******************************************
函数名称:delay
功    能:延时一段时间
参    数:time--延时长度
********************************************/
void delay(uint time)
{
    uint i;
    for(i = 0;i < time;i++)     _NOP();
}                      
/*******************************************
函数名称:Delay5ms 功    能:延时约5ms
********************************************/
void Delay5ms(void)
{
    uint i=40000;
    while (i != 0)
    {
        i--;
    }
}
/*******************************************
函数名称:WaitForEnable
功    能:等待1602液晶完成内部操作
********************************************/
void WaitForEnable(void)
{
    P4DIR &= 0x00;  //将P4口切换为输入状态
    CLR_RS;
    SET_RW;
    _NOP();
    SET_EN;
    _NOP();
    _NOP();
 
    while((P4IN & Busy)!=0);  //检测忙标志
    CLR_EN;
    P4DIR |= 0xFF;  //将P4口切换为输出状态

/*******************************************
函数名称:write_com
功    能:向液晶模块写入命令
********************************************/
void write_com(uchar cmd)
{
    WaitForEnable();   // 检测忙信号?
   
    CLR_RS; 
    CLR_RW;
    _NOP();
    DataPort = cmd;             //将命令字写入数据端口
    _NOP();     
   
    SET_EN;                     //产生使能脉冲信号
    _NOP();
    _NOP();
    CLR_EN;   
}
 
/*******************************************
函数名称:write_data
功    能:向液晶显示的当前地址写入显示数据
参    数:data--显示字符数据
返回值  :无
********************************************/
void write_data( uchar data )
{
    WaitForEnable();        //等待液晶不忙
    SET_RS;
    CLR_RW;
    _NOP();
    DataPort = data;        //将显示数据写入数据端口
    _NOP();
    SET_EN;                 //产生使能脉冲信号
    _NOP();
    _NOP();
    CLR_EN;  
}
void Write1602(uchar add,uchar dat)
{
 write_com(add);
 write_data(dat);
}
 
void zifuchuan(uchar *ch)
{
  while(*ch!=0)
  write_data(*ch++);
  Delay5ms(); 
}
 
/*******************************************
函数名称:LcdReset
功    能:对1602液晶模块进行复位操作
********************************************/
void LcdReset(void)
{
    CtrlDir |= 0x07;  //控制线端口设为输出状态
    DataDir  = 0xFF;  //数据端口设为输出状态
 
    write_com(0x38);//规定的复位操作
    Delay5ms();
    write_com(0x38);  
    Delay5ms();
    write_com(0x38);
    Delay5ms();
    write_com(0x38);//显示模式设置  
    write_com(0x06);//写字符时整体不移动
    write_com(0x0c);//显示开,不开游标,不闪烁
     write_com(0x01);//显示清屏
    
    
}
 
 /************************主函数****************************/
void main(void)
{
  WDTCTL = WDTPW+WDTHOLD;                   //关闭看门狗
 
  /*下面六行程序关闭所有的IO口*/
    P1DIR = 0XFF;P1OUT = 0XFF;
    P2DIR = 0XFF;P2OUT = 0XFF;
    P3DIR = 0XFF;P3OUT = 0XFF;
    P4DIR = 0XFF;P4OUT = 0XFF;
    P5DIR = 0XFF;P5OUT = 0XFF;
    P6DIR = 0XFF;P6OUT = 0XFF;
 
  P6DIR |= BIT2;P6OUT |= BIT2;//关闭电平转换
   LcdReset(); //复位1602液晶
  // P6DIR&=~BIT0;//先把P6_1口设为输入,上电就是这个状态,这句可要可不要
  P6SEL |= 0x01;//把P6_1口设为ADC输入通道
  ADC12CTL0 = ADC12ON+SHT0_8+MSC; // 打开ADC,设置采样时间
  ADC12CTL1 = SHP+CONSEQ_2; // 使用采样定时器
  ADC12IE = 0x01;// 使能ADC中断
  ADC12CTL0 |= ENC; // 使能转换
  ADC12CTL0 |= ADC12SC;// 开始转换
   write_com(0x82);
  zifuchuan("The volt is:");
  _EINT();
  LPM0;
}
/*******************************************
函数名称:ADC12ISR
功    能:ADC中断服务函数,在这里用多次平均的
          计算P6.0口的模拟电压数值
参    数:无      
返回值  :无
********************************************/
#pragma vector=ADC_VECTOR
__interrupt void ADC12ISR (void)
{
  static uint temp = 0;
  results[temp++] = ADC12MEM0;
  if(temp == 32)
  {
        uchar i;
        unsigned long sum = 0;
        temp = 0;
        for(i = 0; i < 32; i++)
        {
            sum += results[i];
        }
        sum >>= 5;//除以32
       
        Trans_val(sum);
  }
}
/*******************************************
函数名称:Trans_val
功    能:将16进制ADC转换数据变换成三位10进制
          真实的模拟电压数据,并在液晶上显示
参    数:Hex_Val--16进制数据
          n--变换时的分母等于2的n次方      
返回值  :无
********************************************/
void Trans_val(uint dat)
{
    unsigned long temp;
    uint Curr_Volt;
    uchar ptr[3];   
    temp = dat;
    temp = (temp << 5) + dat;  //temp = dat * 33
    //移位比直接乘效率要高
    temp = (temp << 3) + (temp << 1); //temp = temp * 10
    //一个数左移N位等于这个数乘以2的N次方
    Curr_Volt = temp >> 12;//Curr_Volt = temp / 2^n一个数右移N位等于除以2的N次方
    ptr[0] = Curr_Volt/100;
    ptr[1] = Curr_Volt %100/10;
    ptr[2] = Curr_Volt%10;
      //在液晶上显示变换后的结果
    Write1602(0x80+0x40,ptr[0]+0x30);
    Write1602(0x80+0x41,'.');
    Write1602(0x80+0x42,ptr[1]+0x30);
    Write1602(0x80+0x43,ptr[2]+0x30);
     Write1602(0x80+0x44,'V');

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
ZigBee技术语音图像无线监控系统的设计与实现