📄 main.c
字号:
#include <c8051f020.h>
#include <absacc.h>
#include <intrins.h>
#include "lcd_driver.h"
#include "delay.h"
#include "crc.h"
//------------------------
#define uchar unsigned char
#define uint unsigned int
sfr16 DP = 0x82; // data pointer
sfr16 TMR3RL = 0x92; // Timer3 reload value
sfr16 TMR3 = 0x94; // Timer3 counter
sfr16 ADC0 = 0xbe; // ADC0 data
sfr16 ADC0GT = 0xc4; // ADC0 greater than window
sfr16 ADC0LT = 0xc6; // ADC0 less than window
sfr16 RCAP2 = 0xca; // Timer2 capture/reload
sfr16 T2 = 0xcc; // Timer2
sfr16 RCAP4 = 0xe4; // Timer4 capture/reload
sfr16 T4 = 0xf4; // Timer4
sfr16 DAC0 = 0xd2; // DAC0 data
sfr16 DAC1 = 0xd5; // DAC1 data
void SYSCLK_Init(void);
void PORT_Init(void);
void Uart0_Init(void);
void uart0_sentbyte(uchar dat);
void uart0_recbyte(uchar dat);
void PCA0_Init(void);
void ADC0_Init(void);
void adc_cns(void);
void get_value(void);
#define sysclk 22118400 // SYSCLK frequency in Hz
#define baudrate 2400 // Baud rate of UART in bps
#define freq 38000 // Frequency to generate in Hz
#define length 18 //数据长度 + 两字节CRC值
#define begin 10
uchar code welcome[]=" Welcome Innovation Lab ";
float value;
uchar xdata buffer[length+1]="00Tempera:000.00^C";
extern uchar a;
//-----------------------------------------------------------------------------
// MAIN Routine
//-----------------------------------------------------------------------------
void main (void)
{ uchar i;
SYSCLK_Init(); // initialize oscillator
PORT_Init(); // initialize crossbar and GPIO
LCD_Init();
LCD_string(1,1,welcome); // 欢迎使用界面
Uart0_Init();
PCA0_Init();
ADC0_Init();
buffer[length] = 0;
for (i=0;i<200;i++)
delay(100,100);
LCD_cmd(0x01); //清屏
EA = 1;
while(1)
{
get_value();
CRC16_Get(buffer,length);
LCD_string(1,1,buffer+2);
uart0_sentbyte(0xff); //起始码
for(i=0;i<length;i++)
{
uart0_sentbyte(buffer[i]);
}
uart0_sentbyte(0xfe); //结束码
for (i=0;i<200;i++)
delay(100,100);
}
}
void SYSCLK_Init (void)
{
int i; // delay counter
WDTCN = 0xde; // disable watchdog timer
WDTCN = 0xad;
OSCXCN = 0x67; // start external oscillator with
for (i=0; i < 256; i++); // XTLVLD blanking interval (>1ms)
while (!(OSCXCN & 0x80)); // Wait for crystal osc. to settle
OSCICN = 0x88; // select external oscillator as SYSCLK
// source and enable missing clock
// detector
}
//-----------------------------------------------------------------------------
// PORT_Init
//-----------------------------------------------------------------------------
//
// Configure the Crossbar and GPIO ports
//
void PORT_Init (void)
{
XBR0 = 0x0c; // 串口0允许
XBR1 = 0x00;
XBR2 = 0x40; // Enable crossbar and weak pull-ups
P0MDOUT |= 0x07;
P1MDOUT = 0xff;
//P2MDOUT = 0xff;
//P3MDOUT = 0xff;
P74OUT = 0xff; // P4-P7配置为推挽方式
}
void Uart0_Init(void)
{
SCON0 = 0x40; // SCON0: mode 1, 8-bit UART, disenable RX //0x50 enable RX
TMOD |= 0x20; // TMOD: timer 1, mode 2, 8-bit reload
TH1 = -(sysclk/baudrate/192); // set Timer1 reload value for baudrate
CKCON |= 0x00; // Timer1 uses SYSCLK/12 as time base
PCON |= 0x80; // SMOD0 = 1
TR1 = 1; // start Timer1
// ES0 = 1; // enable UART0 interrupts
}
void uart0_sentbyte(uchar dat)
{
SBUF0 = dat;
while(TI0 == 0);
TI0 = 0;
}
void uart0_recbyte(uchar dat)
{
while(RI0 == 0);
dat = SBUF0;
RI0 = 0;
}
//-----------------------------------------------------------------------------
// PCA0_Init
//-----------------------------------------------------------------------------
//
// Configure PCA0: PCA uses SYSCLK as time base; overflow interrupt
// disabled.
// Module 0 configured in Frequency Output mode to generate a frequency equal
// to the constant FREQ.
//
void PCA0_Init (void)
{
// configure PCA time base to use SYSCLK; overflow interrupt disabled
PCA0CN = 0x00; // Stop counter; clear all flags
PCA0MD = 0x02; // 系统时钟四分频
// Configure Module 0 to Frequency Output mode to toggle at 2*FREQ
PCA0CPM0 = 0x46; // Frequency Output mode
PCA0CPH0 = sysclk/freq/8; // Set frequency
// Start PCA counter
CR = 1;
}
void ADC0_Init(void)
{
ADC0CN = 0x00; // ADC0 禁止; 正常跟踪模式向AD0BUSY写‘1’启动ADC0转换 ADC0数据右对齐
REF0CN = 0x03; // 禁止温度传感器, 片内 VREF,和 VREF 输出缓冲器
AMX0CF = 0x00; //
AMX0SL = 0x00; // 选择AIN0作为ADC多路转换输出
ADC0CF = (sysclk/2500000) << 3; // ADC转换时钟2.5MHz
ADC0CF &= ~0x07; // PGA增益 = 1
EIE2 &= ~0x02; // 禁止ADC0中断
AD0EN = 1; // 使能ADC0
}
void adc_cns(void)
{
uint i;
uint v;
value = 0x00000000;
for(i=0;i<10000;i++)
{
AD0INT = 0;
AD0BUSY = 1; // 向AD0BUSY写1将启动转换
while(AD0INT == 0);
v = ADC0H*256;
v |= ADC0L;
value = value+v;
}
value = value/10000;
value = value*2.43/4096;
}
void get_value(void)
{
float res,res0;
int tempera;
adc_cns(); //(res/(10K+res)-100/10100)*4*51 = value
res = value*101+204; //4V基准,51倍放大倍数
res0= 20400-101*value;
res = res*10000/res0; //得到铂丝电阻值
tempera = (res-100)*100/0.3851; //得到温度值并放大100倍
if(tempera&0x8000) //如果温度为负数,转化为正数
{
tempera = ~tempera;
tempera += 1;
buffer[begin]='-';
}
else
buffer[begin]='+';
buffer[begin+1]=(uchar)(tempera/1000)+'0';
buffer[begin+2]=(uchar)(tempera/100)%10+'0';
buffer[begin+3]='.';
buffer[begin+4]=(uchar)(tempera/10)%10+'0';
buffer[begin+5]=(uchar)tempera%10+'0';
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -