×
单片机 > 单片机程序设计 > 详情

51的测试程序(主要是用仿真串口进行测试)

发布时间:2020-06-05 发布时间:
|

/*
**************************************************************************************
**************************************************************************************
*/
#include
#include
#include "lcd_51.h"
#include "delay_51.h"
#include "24c64.h"
#include "key.h"
//#include "adc0832.h"


#define    uchar    unsigned char
#define    uint     unsigned int

//adc0832部分
uchar ReadAdc0832( uchar channel ) reentrant;
//ADC0832端口定义
#define     ADC0832_SCK_H      P1_1 = 1
#define     ADC0832_SCK_L      P1_1 = 0

#define     ADC0832_DIDO_H     P1_2 = 1
#define     ADC0832_DIDO_L     P1_2 = 0
#define     ADC0832_DIDO       P1_2

#define     ADC0832_CS_H       P1_0 = 1
#define     ADC0832_CS_L       P1_0 = 0

//按键部分
uchar sure = 0;
uchar model = 0;
uchar add_b = 0;
uint  add_p = 0x0000;

//串口部分

//uchar flag44 = 0;
//uchar flagadc0832 = 0;
//uchar flag24c64 = 0;
//uchar flagshumaguang = 0;
uchar flagwhole = 5;
//uchar flagno = 1;
uchar flagfillallow = 0;

uchar flagsendmessage44 = 0;
uchar flagsendmessageadc0832 = 0;
uchar flagsendmessageshumaguang = 0;
uchar flagsendmessage24c64 = 0; 
uchar flagdoing24c64 = 0;

//波特率宏定义
#define RELOAD_COUNT 0xfd; //SMOD=1, crystal=11.0592, baud= 19200
//#define RELOAD_COUNT 0xFa //SMOD=1, crystal=11.0592, baud= 9600
//#define RELOAD_COUNT 0xf4 //SMOD=1, crystal=11.0592, baud= 4800
//#define RELOAD_COUNT 0xe8 //SMOD=1, crystal=11.0592, baud= 2400


//缓冲区 
#define  Rec_Max       9   //定义最大值
#define  COMRECSIZE    16  //定义缓冲区大小

uchar    Rec_buf[COMRECSIZE];  
uchar    *Point2Rec_buf;    //定义指向数组Rec_buf的指针

uchar    Rec_n = 0;        //接收字节个数初始化为0
uchar    RecFullFlag = 0;  //接收满标志初始化为0


//-----------------------------------------------------串口部分接口函数--------------------------------------------------
/*
********************************************************************
** 函数名:串口初始化函数
** 例子  : UART_Init();
** 
********************************************************************
*/
void UART_Init( void ) 
{
 SCON |= 0x50;     //串口工作方式1, 波特率可变, 波特率由T1决定, 允许接收位REN = 1. 无奇偶校验位
 PCON |= 0x80;     //波特率加倍
 TMOD |= 0x20;     //T1, 8位自动, 方式2, 之所以选择工作方式2是因为它有自动加载功能,可以避免程序反复装入初值引起的误差
 
 TH1 = RELOAD_COUNT; //赋初值高8位TH     RELOAD_COUNT由前宏定义
 TL1 = RELOAD_COUNT; //赋初值低8位TH
 ES = 1;             //开串口中断 
 ET1 = 0;            //禁止T1中断允许, 以免产生不必要的中断带来的频率误差
 TR1 = 1;         //打开T1

 //EA = 1;           //注意, 还没有打开全局中断
}

//串口接收中断服务程序
void serial_INT4( void ) interrupt 4
{
    if( RI )
    { 
     RI = 0;                  //硬件置位,软件清零
  if( flagdoing24c64 == 0 )
  {
  switch( SBUF )
  {
   case '1': 
    {
     //4*4
     flagwhole = 1;
     flagsendmessage44 = 1;
     LCD_write_string( 1, 0, " made by hebei   " );
        LCD_write_string( 2, 0, " TEST 4*4 --> 0   " );
    }  break;

   case '2': 
    {
     //ADC
     flagwhole = 2;
     flagsendmessageadc0832 = 1;
     LCD_write_string( 1, 0, " made by hebei   " );
        LCD_write_string( 2, 1, "TEST ADC-->        " );
    }  break;

   
   case '3': 
    {
     //shumaguang
     flagwhole = 3; 
     flagsendmessageshumaguang = 1;
     LCD_write_string( 1, 0, " made by hebei   " );
        LCD_write_string( 2, 0, "TEST shumaguang  " );
    }  break;

   case '4': 
    {
     //24C64
     flagwhole = 4;
     flagsendmessage24c64 = 1;
     LCD_write_string( 1, 1, "0000 >0 is      " );  //
     LCD_write_string( 2, 0, "                 ");
     
    }  break;

     case '5': 
    {
     //结束
     flagwhole = 5;
     LCD_write_string( 1, 0, " made by hebei   " );
         LCD_write_string( 2, 0, "    NO TEST       " );
    }  break;

   
  }
  }

  if( flagdoing24c64 == 1 )
  {
  if( flagfillallow == 1 )
  {
      Rec_buf[Rec_n++] = SBUF;
  
      if( Rec_n == Rec_Max )
       RecFullFlag = 1;
  }
    }
 }
 
 return;
}


/*
********************************************************************
** 函数名:串口发送一个字符
** 例子  : UART_Sendstr( 'a' );
**
** 说明  : UART_SendCh(10);  //
**      UART_SendCh(13);  //回车换行 
********************************************************************
*/
void UART_SendCh( uchar Tmp_char )  
{
 TI = 0;
 SBUF = Tmp_char;
 while( !TI )
  {;}
}

/*
********************************************************************
** 函数名:串口发送字符串函数 
** 例子  : UART_Sendstr( "how are you?" );
** 
********************************************************************
*/
void UART_SendStr( uchar *str )    
{  
 ES=0;      //disable uart0 interrupt;
 while( *str ) 
 {  
   TI = 0; 
  SBUF = ( *str );  
  ++str;   
  while( !TI )
  {;}   //waitting for sending finished.
 } 
 TI=0;    
 ES=1;
}

//-----------------------------------------------------串口部分接口函数结束--------------------------------------------------

 

//-----------------------------------------------------外部中断0部分接口函数(24c64按键)--------------------------------------------------
//外中断初始化
void Int0init( void )
{
 EX0 = 1;  //允许外中断0
 IT0 = 1;  //边沿触发
}

//
void modelchang( void )
{
    model++;
 model %= 3;    //model在0-2之间
 switch( model )
 {
  case 0: LCD_write_char( 1, 0, ' ' ); LCD_write_char( 1, 6, ' ' ); break;
  case 1: LCD_write_char( 1, 0, '>' ); LCD_write_char( 1, 6, ' ' ); break;
  case 2: LCD_write_char( 1, 0, ' ' ); LCD_write_char( 1, 6, '>' );  break;
  default: break;
 }
}

//
void add( void )

 uint k = add_p;
    switch( model )
    {
        case 1: 
       add_p++;
    add_p %= 0x000A;
    LCD_write_char( 1, 4, ( add_p & 0x000f ) + 0x30 ); break;
  case 2: 
    add_b %= Rec_Max;
    LCD_write_char( 1, 7, ( add_b & 0x000f ) + 0x30 ); 
    LCD_write_char( 1, 12, I2cReadDataFromAddr( 0xa0, k + add_b ) ); //从24C64里面读数据
    add_b++;
    break;

  default : break;
    }
}

//确定
void ok( void )
{
 sure = 1;
}

//外中断0服务程序
void int0_int( void ) interrupt 0
{
 EA = 0;   //禁止再次外中断
 
 if( ( P3 & 0x3c ) != 0x3c )
 {
   delay_nms( 20 );             //去除抖动
  if( ( ( P3 & 0x3c ) != 0x3c ) )
  {    
   switch( P3 & 0x3c )
      {
           //模式
           case 0x30 : modelchang(); break;
           //加
           case 0x28 : add(); break;
           //确定
           case 0x18 : ok(); break;

           default : break;
      }
  }
 }
 
 EA = 1;   //打开外中断
}

//-----------------------------------------------------外部中断0部分接口函数结束--------------------------------------------------


//-----------------------------------------------------芯片74HC595以及74HC139部分接口函数(数码管)--------------------------------------------------

//595端口定义
#define     HC595_SHCP_H       P0_0 = 1
#define     HC595_SHCP_L       P0_0 = 0
#define     HC595_DS_H         P0_1 = 1
#define     HC595_DS_L         P0_1 = 0
#define     HC595_STCP_H       P0_2 = 1
#define     HC595_STCP_L       P0_2 = 0

//139端口定义
#define     HC139A_H            P0_3 = 1
#define     HC139A_L            P0_3 = 0
#define     HC139B_H            P0_4 = 1
#define     HC139B_L            P0_4 = 0

//共阳a-7 b-6 c-5 d-4 e-3 f-2 g-1 h-0
uchar code Atab[] =     //注意,此处要定义为code             
{
        0x03,/*0*/
        0x9F,/*1*/
        0x25,/*2*/
        0x0D,/*3*/
        0x99,/*4*/
        0x49,/*5*/
        0x41,/*6*/
        0x1F,/*7*/
        0x01,/*8*/
        0x09,/*9*/
};

//139译码
void HC139_Sendbyte( uchar senddata )
{
    switch( senddata )
    {
        case 0: HC139A_L; HC139B_L; break;
        case 1: HC139A_H; HC139B_L; break;
        case 2: HC139A_L; HC139B_H; break;
        case 3: HC139A_H; HC139B_H; break;
        default: break;
    }
}

/**********************************
** 函数作用:向595发送一个字节数据的低n位
** 入口参数:要写的字节 senddata
** 返回值  : 无
***********************************/
void HC595_Send( uchar Btemp )
{
    uchar i;
    for( i = 0; i < 8; i++ )
    {
        if( 0x01 & Btemp )    //先发送低位, 再发高位
        HC595_DS_H;

        else
        HC595_DS_L;
  
        HC595_SHCP_L;
  //asm("nop");
        HC595_SHCP_H;
  //asm("nop");
  
        Btemp = Btemp >> 1;
    }

 //锁存    
 HC595_STCP_L;
 //delay_nus( 1 );
 HC595_STCP_H;
}                    

//数码管显示
void NumDisplay( unsigned char Bit, unsigned char num )
{  
    HC139_Sendbyte( Bit );
 HC595_Send( Atab[num] );   //第3位数字显示数num 
}

//注意此函数在循环体中使用
//内部包含5ms延时
void DataDisp( long int datal )
{
    uchar i;
 unsigned int wei[4]; 
    wei[0] = datal / 1000;
 wei[1] = (datal - wei[0] * 1000) / 100;
 wei[2] = (datal - wei[0] * 1000 - wei[1] * 100) / 10;
    wei[3] = datal % 10;

 //显示停留时间
    for( i = 0; i < 5; i++ )
 {
    NumDisplay( 0,wei[0] );
    delay_nms( 3 ); 

    NumDisplay( 1, wei[1] );
    delay_nms( 3 ); 

    NumDisplay( 2, wei[2] );
    delay_nms( 3 ); 

    NumDisplay( 3, wei[3] );
    delay_nms( 3 ); 
 }
}

//-----------------------------------------------------芯片74HC595以及74HC139部分接口函数(数码管)结束--------------------------------------------------


//-----------------------------------------------------ADC0832驱动部分函数--------------------------------------------------
/*
********************************************************************
** 函数名 :ADC0832读数据程序
** 入口   :需转换通道channel  [0:1]
** 返回   : 无符号字符型 uchar
** 例子   : Data_adc = ReadAdc0832( 0 );   //读取adc0832芯片的0通道模拟电压
** 说明   : 使用时请在芯片加上精准电压源, 建议用专用芯片
********************************************************************
*/

//工作时序
//当cs由高变低时,选中ADC0832。在时钟的上升沿,DI端的数据移入ADC0832内部的多路地址移位寄存器。
//在第一个时钟期间,Dl为高,表示启动位,紧接着输入两位配置位。当输入启动位和配置位后,选通输入模拟通道,转换开始。
//转换开始后,经过一个时钟周期延迟,以使选定的通道稳定。ADC0832接着在第4个时钟下降沿输出转换数据。
//数据输出时先输出最高位(D7~DO);输出完转换结果后,又以最低位开始重新输出一遍数据(D7~DO),两次发送的最低位共用。当片选cS
//为高时,内部所有寄存器清0,输出变为高阻态。如果要再进行一次模傲转换,片选cs必须再次从高向低跳变,后面再输入启动位和配置位

//adc0832读数据
uchar ReadAdc0832( uchar channel ) reentrant
{
    uchar i = 0;
    uchar outdata = 0;
    //初始化: 选通 数据口保持高电平
 //当cs由高变低时,选中ADC0832。在时钟的上升沿,DI端的数据移入ADC0832内部的多路地址移位寄存器
    ADC0832_CS_L;   // 使能
    ADC0832_DIDO_H; //
    ADC0832_SCK_L;  //第一次触发
    _nop_();
 _nop_();
    ADC0832_SCK_H;  //
    _nop_();
 _nop_();
 
 //模拟通道的选择及单端输入和差分输入的选择
 ADC0832_DIDO_H;
    ADC0832_SCK_L;  //第二次触发
 _nop_();
 _nop_();
    ADC0832_SCK_H;
    _nop_();
 _nop_();
 
 if( channel == 1 ) 
     {
         ADC0832_DIDO_H;
     }
 
    else
     {
         ADC0832_DIDO_L;
     }
 ADC0832_SCK_L;  //第三次触发
    _nop_();
 _nop_();
 ADC0832_SCK_H;
 _nop_();
 _nop_();
 
 
    ADC0832_SCK_L;
 _nop_();
 _nop_();
    ADC0832_DIDO_H;   //置为输入准备读数据
    ADC0832_SCK_H;
 _nop_();
 _nop_();

 outdata = 0;     //初始化
 
    //读数据D7~D0
    for( i = 1; i <= 8; i++ )
     {
         if( ADC0832_DIDO == 1 )
             {
     outdata |= 0x01;
    }

   ADC0832_SCK_H;
         ADC0832_SCK_L;

         outdata = outdata << 1; //左移一位
     }

    //此函数不再读数据D0~D7  (注意D0位重叠)
    ADC0832_CS_H;        //禁止
     
 return outdata;
}
//-----------------------------------------------------ADC0832驱动部分函数结束--------------------------------------------------


//显示标签
void sendlogo( void )
{
 UART_SendCh(10);       //   
 UART_SendCh(13);
 UART_SendStr( "                       Test Message            " );
 UART_SendCh(10);       //   
 UART_SendCh(13);
 UART_SendStr( "***************************************************************************" );
 UART_SendCh(10);       //   
 UART_SendCh(13);
 UART_SendStr( "                                  1  --->  test 4*4                 " );
 UART_SendCh(10);       //   
 UART_SendCh(13);
 UART_SendStr( "                                  2  --->  test ADC0832        " );
 UART_SendCh(10);       //        
 UART_SendCh(13);  
 UART_SendStr( "                                  3  --->  test shumaguang          " );  
 UART_SendCh(10);       //   
 UART_SendCh(13);       // 
 UART_SendStr( "                                  4  --->  test I2C(24C64)           " );
 UART_SendCh(10);       //   
 UART_SendCh(13);
 UART_SendStr( "                                  5  --->  no  test                  " );
 UART_SendCh(10);       //   
 UART_SendCh(13);
 UART_SendCh(10);       //   
 UART_SendCh(13);
 UART_SendStr( "  06AotoControl   QiXi.Qin   dongxixiaonanbei@163.com" );
 UART_SendCh(10);       //   
 UART_SendCh(13);
 UART_SendStr( "***************************************************************************" );
 UART_SendCh(10);       //   
 UART_SendCh(13);
 UART_SendStr( "Please enter you want to test   -------->     " ); 
}


//总初始化
void Device_init( void )
{
 LCD_init();
 Int0init();
 UART_Init();
 EA = 1;
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~主函数~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void main( void )
{
 uchar tmp;
 uint shu = 9999;  //数码管初值
 uchar new = 0;
 uchar old = 0;
 
 Device_init();   //总初始化

    while( 1 )
 {
  EA = 0;  //禁止中断,以免写液晶时出现不必要显示的字符

  //4*4
  if( flagwhole == 1 )
  {
   if( flagsendmessage44 == 1 )
   {
    UART_SendCh(10);       //   
    UART_SendCh(13);
    UART_SendStr( "    " );
    UART_SendCh(10);       //   
    UART_SendCh(13);
    flagsendmessage44 = 0;
    
   }
   new = KeyScan44();
   if( old != new )
   {
    old = new;
    LCD_write_datalongint( 2, 14, new );

    if( new < 10 )
     LCD_write_char( 2, 15, ' ' );
   }   
  }

  //AD采样
  if( flagwhole == 2 )
  {
   if( flagsendmessageadc0832 == 1 )
   {
    UART_SendCh(10);       //   
    UART_SendCh(13);
    UART_SendStr( "    " );
    UART_SendCh(10);       //   
    UART_SendCh(13);
    flagsendmessageadc0832 = 0;
    
   }

   tmp = ReadAdc0832( 0 );
   
   //清除一些不必要的显示
   if( tmp < 100 )
   LCD_write_char( 2, 15, ' ' );
   if( tmp < 10 )
   LCD_write_char( 2, 14, ' ' );
 
   //显示该值
   LCD_write_datalongint( 2, 13, tmp );
  }

  //数码管
  if( flagwhole == 3 )
  {
   if( flagsendmessageshumaguang == 1 )
   {
    UART_SendCh(10);       //   
    UART_SendCh(13);
    UART_SendStr( "    " );
    UART_SendCh(10);       //   
    UART_SendCh(13);
    flagsendmessageshumaguang = 0;
    
   }
   DataDisp( shu-- ); 
  }

  //I2C(24C64)
  if( flagwhole == 4 )
  {
   if( flagsendmessage24c64 == 1 )
   {
    UART_SendCh(10);       //   
    UART_SendCh(13);       //
    UART_SendStr( "    UART_SendCh( Rec_Max / 10 + 0x30 );
    UART_SendCh( Rec_Max % 10 + 0x30 );
    UART_SendStr( " words to the Device 24C64> " );
    UART_SendCh(10);       //   
    UART_SendCh(13);       // 
    flagsendmessage24c64 = 0;  //标志清0

    flagfillallow = 1;  //允许开始装入数据
    flagdoing24c64 = 1; 
    Rec_n = 0;
   }

   if( RecFullFlag == 1 )                   //如果装满
   {
    UART_SendCh(10);       //   
    UART_SendCh(13);       //
    UART_SendStr( ">>>>>You had finished sendding " );
    UART_SendCh( Rec_n / 10 + 0x30 );
    UART_SendCh( Rec_n % 10 + 0x30 );
    UART_SendStr( " words to Device 24C64!  " );
    UART_SendCh(10);       //   
    UART_SendCh(13);       //
    UART_SendStr( ">>>>>you can press 3 Keys on the board to see what you had send to the 24C64, " );
    UART_SendCh(10);       //   
    UART_SendCh(13);       //
    UART_SendStr( ">>>>>if you press the key *sure*, you can break out the job now, and it is the only way to break out ^_^ ");
    UART_SendCh(10);       //   
    UART_SendCh(13);
    RecFullFlag = 0; 
    Rec_n = 0;                               //准备重新接收
   }

   if( sure == 1 )
   {
    sure = 0;
    I2c_Write_n( 0xa0, add_p, Rec_buf, Rec_Max);
    LCD_write_array( 2, 2, Rec_buf ); //在1602上显示该数组字符串
    UART_SendCh(10);       //   
    UART_SendCh(13);
    UART_SendStr( " " );
    UART_SendCh(10);       //   
    UART_SendCh(13);
    flagdoing24c64 = 0;
   }
  }

  //正常状态
  if( flagwhole == 5 )
  {
   flagwhole = 0;     //置标志为0,不做任何测试
   flagdoing24c64 = 0; //任务24C64的工作正在执行标志
   LCD_write_string( 1, 0, " made by hebei   " );
      LCD_write_string( 2, 0, "    NO TEST       " );
   sendlogo();  //显示标签
  }

  EA = 1;  //打开全局中断
 }

}

 



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

热门文章 更多
如何升级STM32单片机的代码