⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kongwen.c

📁 对8051cf020的温度控制和液晶显示急串口上传的代码
💻 C
📖 第 1 页 / 共 4 页
字号:
  //包含文件

#include <c8051f020.h>        
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include "F020_FlashPrimitives.h"
// 16-bit 特殊功能寄存器定义 'F02x

sfr16 DP       = 0x82;              // 数据指针
sfr16 TMR3RL   = 0x92;              // 定时器3,重装载数值寄存器
sfr16 TMR3     = 0x94;              // 定时器3计数器
sfr16 ADC0     = 0xbe;              // adc0数据
sfr16 ADC0GT   = 0xc4;              // adc0窗口比较器上限
sfr16 ADC0LT   = 0xc6;              // adc0窗口比较器下限
sfr16 RCAP2    = 0xca;              // 定时器2捕捉/重装载
sfr16 T2       = 0xcc;              // 定时器2
sfr16 RCAP4    = 0xe4;              // 定时器4捕捉/重装载
sfr16 T4       = 0xf4;              // 定时器4
sfr16 DAC0     = 0xd2;              // DAC0 数据
sfr16 DAC1     = 0xd5;              // DAC1 数据

// 函数原型
//*****************************************//
//************以下为系统函数*****************//
void main (void);                                                //主函数
void sysclk_init (void);  	                                     //系统时钟初始化函数
void port_init (void);                                            //端口口初始化函数
void uart0_init (void);                                          //串口初始化函数
void disable_dog(void);                                          // 禁止看门狗
void init_dac1(void) ;                                           //初始化dac1    
void adc0_init (void);                                           //初始化adc0
float temperature(unsigned char gain,unsigned int adc0_data);    //温度测量函数
float get_temperature(void);                                     //获得当前cpu温度
void delay_time(unsigned int time_value);                        //延时函数
void micro_init_dac1(void);                                      //微动初始化dac1
void timer4_init (int counts);                                   //定时器4初始化函数
void timer0_init(unsigned char counts);                          //定时器0初始化函数
void init_dac0(void);
void timer4_ISR (void);                                          //定时器4中断子程序
void timer0_ISR(void);                                           //定时器0中断子程序
void UART0_ISR (void);                                           //接收中断
//*****************************************//
//*****************************************//

//************超级终端控制函数数*************/
void Tdata(char *str);   //串口发送数据
void Tdatar(char s);    //串口发送单个字符

char * trim(char * str);   //去除字符串两边的空格
char atoii(char chr);    //相当于c语言中的atoi函数
float atoff(char *);      //相当于c语言中的atof函数
char * strstr1(char *,char *);  //字符串查找命令//相当于c语言中的strstr函数
char strlen1(char *);           //字符串长度命令//相当于c语言中的strlen函数
char * strcat1(char *,char *);  //字符串合并命令//相当于c语言中的strcat函数
char * strmid(char * s,unsigned char begin,unsigned char longth); 
 //从字符串中取字符s:字符串指针,begin:开始位置,longth:要取的
void clr_datarx(void);          //清除串口接收数组
char hwtanalyze(void);          //系统内部自检
char *mysprint(float discode,unsigned char a1);//浮点数到字符串转换
#define atoffERROR 0   //atoff函数含非法字符返回错误标志
char uartflag;   //记录本次串口是否接收完毕
char uartcount=0;  //记录本次串口接收个数
xdata char *data_tx;
char display_flag=1;     //显示标志,=0表示显示提示信息,=1表示不现实提示信息
unsigned char c_end[3]={13,10,0}; //回车换行字符串结束
char * lookresult;    //通道命令解释时的辅助变量
char *lookresult1;    //通道命令解释时的辅助变量
char *lookresult2;    //通道命令解释时的辅助变量
char xdata array[100];      
static char xdata data_rx[50];        //接收缓冲区
float get_voltage(void);
float xdata result1[503];
float get_real_value(unsigned char temp);
float xdata real_value[4];
unsigned int get_init_voltage(void);
unsigned char read_lcd();
void set_v_out(unsigned int voltage);


void FLASH_ByteWrite (FLADDR addr, char byte, bit SFLE);
unsigned char FLASH_ByteRead (FLADDR addr, bit SFLE);
void FLASH_PageErase (FLADDR addr, bit SFLE);

void adc0_single_init (unsigned char channel);      //select adc channel 
void delay_us_time(unsigned int time_value);
float get_bo_res(void);
float get_real_res(unsigned char temp); 

float get_real_res_value(unsigned int temp);

void set_plot_address(unsigned char address);//设定CGRAM地址到地址计数器(AC);
void set_irram_address(unsigned char address);//SR=1:AC5-AC0为垂直卷动地址SR=0:AC3-AC0为ICON IRAM地址
void expend_cmd(unsigned char re,unsigned char g);//RE=1: 扩充指令集动作RE=0: 基本指令集动作
void set_shutdowm(unsigned char aa);//SL=1:脱离睡眠模式SL=0:进入睡眠模式
void reverse_video(unsigned char row);//选择4行中的任一行作反白显示,并可决定反白与否
void irram_curl(unsigned char temp);//SR=1:SR=0:
void wait_order(void); //将DDRAM填满"20H",并且设定DDRAM的地址计数器(AC)到"00H"
unsigned char read_ram(void);//从内部RAM读取资料(DDRAM/CGRAM/IRAM/GDRAM)
void write_ram(unsigned char temp_data);//写入资料到内部的RAM(DDRAM/CGRAM/IRAM/GDRAM)
unsigned char read_add_count(void);//读取同时可以读出位址计数器(AC)的值
unsigned char read_busy_flag(void);//功能:读取忙碌状态(BF)可以确认内部动作是否完成
void set_ddram(unsigned char address);//设定DDRAM地址到地址计数器(AC)
void set_cgram(unsigned char address);//功能:设定CGRAM位址到位址计数器(AC)
void cmd_set(unsigned char aa);//功能:DL=1(必须设为1)   RE=1;扩充指令集动作    RE=0:基本指令集动作
void lcd_cursor_dis(unsigned char sc,unsigned char rl);//设定游标的移动与显示的移位控制位元;这个指令并不改变DDRAM的内容
void lcd_add_reset(void);   //把DDRAM位址计数器调整为"00H",游标回原点,该功能不影响显示DDRAM功能:
                            //执行该命令后,所设置的行将显示在屏幕的第一行。显示起始行是由Z地址计数器控制的,
                            //该命令自动将A0-A5位地址送入Z地址计数器,起始地址可以是0-63范围内任意一行。
						    //Z地址计数器具有循环计数功能,用于显示行扫描同步,当扫描完一行后自动加一。
						    //指定在资料的读取与写入时,设定游标移动方向及指定显示的移位
void lcd_bit_add_reset(void);   //把DDRAM位址计数器调整为"00H",游标回原点,该功能不影响显示DDRAM
void lcd_clear(void);   //清除显示屏幕,把DDRAM位址计数器调整为"00H"
void lcd_swich(unsigned char d,unsigned char c,unsigned char b);//D=1;整体显示ON     C=1;游标ON     B=1;游标位置ON  后3位
void lcd_init(void);
void send_lcd_data(char *str);

void lcd_display(unsigned char page);


//*****************************************//
//************以下是命令分析函数*************//
char help_an();                                                  //帮助函数
void inchworm_init(void);                             //实际上是初始化dac0和dac1

//**********系统变量*************//
#define sysclk          22118400                                 // 系统时钟频率
#define BAUDRATE        9600                                     // 串口波特率
#define SAMPLE_RATE_DAC 80000L                                   // DA采样频率
#define PHASE_PRECISION 65536                                    // 相位累加器
typedef enum Waveform                                            //定义枚举型变量
{                 
    heat,                     //一直加热
	adjust,                   //调整温度	
	res,                      //显示阻值
	tem,                      //显示温度
	vol,                      //显示温度
    off      
}Waveform;
//*******************************************************//
//*******************************************************//
typedef struct robot                           //定义接受结构
  {                        					//
                           					//
     unsigned char manner; 					//
    unsigned int speed_left;               //
    unsigned int speed_right;              //
     unsigned int speed_rotate;           
	 unsigned int robot_position;
	 unsigned char base_value;
	 unsigned int delay_value;
	 unsigned int v_out;
  }robot;
robot xdata robot1={17,10,10,200,10,100,100,0};
robot xdata robot2={17,10,10,200,10,100,100,0};
unsigned char go_stop=0;           //运行变量
char robot_an();                   //分析接收字符,判断处理


//*******************************************************//
//*******************************************************//
unsigned int frequency1 = 10;                                  // 输出频率默认10
unsigned int frequency2=10;                                    // 输出频率默认10
unsigned int phase_add1 = 10 * PHASE_PRECISION / SAMPLE_RATE_DAC;  //全局累加相位1
unsigned int phase_add2=10* PHASE_PRECISION / SAMPLE_RATE_DAC;     //全局累加相位2

Waveform output_waveform = off;                                     //默认没有输出
//******************************//
//*******lcd位控制变量*************//sbit lcd_data1_cmd=P2^0;                                               //
sbit lcd_r1w=P2^1;                //h,read                                           //
sbit lcd_en1_lach=P2^2;                                               //
sbit lcd_ps_select=P2^3;          //h,prolell                                              //
sbit lcd_cs1=P2^4;                                                //
sbit solid=P2^5;                                             //

unsigned long test_value_set=200000;
unsigned char repeat_value=0;
unsigned char get_id(void);
int xdata result[11];
int xdata testqqq[20];


 float xdata q3=-153.1;
 float xdata q2=874.2;
 float xdata q1=2956.7;





//**************************************************************************************//
//**************************************************************************************//
//主程序开始
void main(void)
{
  float xdata temp_res=0.0,temp_tem=0.0;

  unsigned int w=9;
  long resistance=0;
  unsigned long test=0;
  unsigned char q_aa=0;
  int temp1=0;

  disable_dog();
  sysclk_init();
  port_init();



  adc0_init ();	
  init_dac1(); 
  init_dac0();


  lcd_init();
  lcd_clear();	 
  lcd_display(1);
  delay_time(3000);
  lcd_display(2);
  delay_time(3000);

  solid=0; 
  IP|=0x18;
  adc0_init ();	
  init_dac1(); 
  init_dac0();
  timer4_init(sysclk/SAMPLE_RATE_DAC); 
  uart0_init ();    
  
  delay_time(500);

  Tdatar(13);
  Tdatar(10);

  data_tx="欢迎使用科德威产品 045184322252";
  Tdata(data_tx);
  Tdatar(13);
  Tdatar(10);
  

  EA=1;
  ES0=1;
  uartflag=0;
  while(1)
  {
	  if(uartflag)
		   {
			   w=robot_an();
			   uartflag=0;
		   }
	  if(repeat_value==1)
	      {
		    T4CON=0;
			repeat_value=0;
			real_value[1]=0.0;
			temp1=(int)get_real_res_value(robot1.speed_right);
			resistance=(long)(temp1)*robot1.delay_value/100+11;
			temp1=(int)resistance;

			data_tx="当前电阻值   ";
	 		Tdata(data_tx);
	  		Tdata(mysprint(temp1,0));

			data_tx="   欧姆";
	 		Tdata(data_tx);

			  Tdatar(13);
              Tdatar(10);
			  T4CON |= 0x04;                // 启动定时器4

		  }
        if(repeat_value==2)
	      {
		    T4CON=0;
			q3=-1531000.0;
			repeat_value=0;
			real_value[1]=0.0;
			temp1=(int)get_real_value(5);
			resistance=(long)(temp1)*robot1.delay_value/100;
			temp1=(int)resistance;
			data_tx="当前电压值   ";
	 		Tdata(data_tx);
	  		Tdata(mysprint(temp1,0));

			data_tx="   V";
	 		Tdata(data_tx);

			  Tdatar(13);
              Tdatar(10);
			  T4CON |= 0x04;                // 启动定时器4
		  }
        if(repeat_value==3)
	      {
		    T4CON=0;
			repeat_value=0;
			real_value[1]=0.0;
			temp_res=get_real_res_value(robot1.speed_right);
			temp_res=temp_res*robot1.delay_value/100+11;
			temp_tem=q1-100*pow(q2-q3*(1-temp_res/1000),0.5);
			if(temp_tem>=100.0)
			   {
			       set_ddram(0x8c);
			       send_lcd_data(mysprint(temp_tem,1));
			   }
            else
			   {
			      set_ddram(0x8c);
			      data_tx=" ";
			      send_lcd_data(data_tx);
				  send_lcd_data(mysprint(temp_tem,1));
			   }        
			data_tx="当前温度值   ";
	 		Tdata(data_tx);
	  		Tdata(mysprint(temp_tem,1));

			data_tx="   度";
	 		Tdata(data_tx);

			  Tdatar(13);
              Tdatar(10);
			  T4CON |= 0x04;                // 启动定时器4
		  }      
  }    
}
//系统初始化,使用外部时钟
void sysclk_init (void)
{
   int i;                           // 延时计数变量
   OSCXCN = 0x67;                   // 启用外部时钟   
   for (i=0; i < 2560; i++) ;        // 等待时钟启动成功
   while (!(OSCXCN & 0x80)) ;     
   OSCICN = 0x88;                   // 选择外部时钟作为系统时钟,使能时钟丢失检测器                                   
for (i=0; i < 2560; i++) ;
}
//端口初始化,配置交叉开关,设置输出方式
void port_init (void)
{
   XBR0     = 0x04;                 // 使能串口0  rx0,tx0连接到2个端口引脚
   XBR1     = 0x00;
   XBR2     = 0x40;                 // 使能交叉开关,设置端口为弱上拉
   P0MDOUT |= 0xff;                 // 
   P1MDOUT= 0xff;                   // 设置p1端口为推挽输出
   P2MDOUT = 0x20;                  //
   P3MDOUT= 0x00;                   // 
   P74OUT=0x00;                     //
}
// 这个子程序将定时器4设置为自装载模式,定时间隔由参数counts改变
void timer4_init (int counts)
{
   T4CON = 0;                       //停止计数设置为自动装载模式
   CKCON |= 0x40;                   // T4M = '1'; 工作时钟选为系统时钟
   RCAP4 = -counts;                 // 设置自动装载数据,注意为负值
   T4 = RCAP4;                      //设置捕捉、重新装载功能
   EIE2 |= 0x04;                    // 使能定时器4中断
  // T4CON |= 0x04;                   // 启动定时器4   
}
//定时器0初始化函数
void timer0_init(unsigned char counts)  
{
  CKCON &=0xf7;                   //定时器0采用系统12分频
  TMOD |=0x02;                    //定时器0设置为自动重装载方式
  TMOD &=0xfe;                    //
  TH0=-counts;                    //装载数据
  TL0=-counts;
 // ET0=1;                          //使能定时器0中断
 // TR0=1;                          //启动定时器0
  
}   
void disable_dog(void)
{
   WDTCN = 0xde;                    // 禁止看门狗定时器
   WDTCN = 0xad;
}
//初始化dac0
void init_dac0(void)
{
  // REF0CN = 0x03;                   // 使能内部电压基准,内部电压缓冲器工作
   DAC0CN = 0x87;                   // 设置DAC0为右对齐数据方式,使能dac0 
                                    //写DAC0H输出
}
//初始化dac1
void init_dac1(void)
{
 //  REF0CN = 0x03;                   // 使能内部电压基准
   DAC1CN = 0x80;                   // 设置DAC1为右对齐数据方式,使能dac1 
                                    //写DAC1H输出
}
//微动dac的初始化
void micro_init_dac1(void)
{
   REF0CN = 0x03;                   // 使能内部电压基准
   DAC0CN = 0x87;
   DAC1CN = 0x87;                   // 设置DAC1为左对齐数据方式使能dac1  定时器4
                                    //溢出更新
}
//尺蠖蠕动方式运动初始化dac0和dac1
void inchworm_init(void)
{
   REF0CN = 0x03;                   // 使能内部电压基准,内部电压缓冲器工作
   DAC0CN = 0x87;                   // 设置DAC0为左对齐数据方式,使能dac0 
                                    //定时器4溢出更新  
   T4CON=0;
   DAC1CN = 0x87;                   // 设置DAC1为左对齐数据方式使能dac
}
//初始化adc0,
void adc0_init (void)
{
   ADC0CN = 0x81;                      // ADC0使能,正常跟踪模式
                                       // 通过写AD0BUSY位启动一次ad转换
                                       // ADC0数据左对齐
   REF0CN = 0x07;                      // 使能温度传感器,使能片内电压基准
                                       // 使能电压基准输出缓冲
 //  AMX0SL = 0x0f;                      // 选择温度传感器的信号输入到dac中
 //  AMX0SL = 0x00;                      // 选择channel  0信号输入到dac中
   ADC0CF = (sysclk/2500000) << 3;     // AD转换时钟为2.5MHz
   ADC0CF |= 0x00;                     // 增益放大倍数为2
   EIE2 &= ~0x02;                      // 禁止ad转换完成中断,采用查询模式
   EIE1 &= ~0x04;    
   delay_time(1000);
}

//单路初始化adc0
void adc0_single_init (unsigned char channel)
{
   AMX0CF=0x00;
   AMX0SL = channel;                      // 选择channel  0信号输入到dac中 
   delay_us_time(2);
}



//延时函数
void delay_time(unsigned int time_value)
{
  int hi,hj;
  for (hi=0; hi<time_value; hi++)
    {
	  for (hj=0; hj < 2000; hj++) ; 
	} 
}
//计算温度函数,其中gain代表内部放大增益,adc0_data表示从ad中读出的数据
float temperature(unsigned char gain,unsigned int adc0_data)
{
  float temp_tem1=0.0,temp_tem2=0.0;
  temp_tem1=(float)((float)adc0_data*2.43);
  temp_tem2=(float)(4096*gain);
  temp_tem1=(temp_tem1/temp_tem2-0.776)/0.00286;
  return temp_tem1;
}
//获得准确的温度
float get_temperature(void)
{
  char i;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -