?? kongwen.c
字號:
//包含文件
#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 + -