1.png (69.88 KB, 下載次數: 31)
下載附件
2023-3-29 18:21 上傳
單片機源程序如下:
#include <reg52.h>
#include <stdio.h>
#include <intrins.h>
#include "lcd016.h"
#define uchar unsigned char
#define uint unsigned int
sbit LCD_RS=P2^0;
sbit LCD_RW=P2^1;
sbit LCD_EN=P2^2;
#define LCD_Data_Port P0
#define BAUD 9600
#define FOSC 12000000L //12mhz
sbit ADCS=P1^0;
sbit ADCLK=P1^1;
sbit ADDI=P1^2;
sbit ADDO=P1^2;
sbit LED=P1^4;
sbit ld=P3^7;
sbit SW=P1^7;
unsigned char cmd; // 存儲藍牙模塊發送的命令
uint dat = 0x00; //AD值
uchar adc=0;//存儲adc0832值
uint voltage = 0;
uchar pwm=0;//PWM占空比參數
uchar time=0;
uchar LED_buffer1[16] = {"ADC:000LX"};//ADC顯示緩沖
uchar LED_buffer2[16] = {"voltage:0.00V"};//電壓顯示緩沖
sbit UART_TX=P3^1; // 定義藍牙模塊 TX 引腳
sbit UART_RX=P3^0; // 定義藍牙模塊 RX 引腳
/*------------------------------------------------
延時函數,含有輸入參數 unsigned int t,無返回值
unsigned int 是定義無符號整形變量,其值的范圍是
0~65535
------------------------------------------------*/
void Delay(unsigned int t)
{
while(--t);
}
void UART_Init() // 定義串口初始化函數
{
SCON=0x50; // SCON 寄存器配置,工作方式為模式 1,允許接收和發送
TMOD=0x20; // TMOD 寄存器配置,使用波特率發生器,不用自動重載
PCON=0x00; //波特率不加倍
TH1=(65536 - (FOSC / 12 / BAUD)); // 定時器 1 的重裝值,用于產生 9600 波特率
TL1=(65536 - (FOSC / 12 / BAUD)); //(65536 - (FOSC / 12 / BAUD))
RI=0;
TI=0; //清0發送中斷標志位
ES=1; // 打開串口中斷開關
TR1=1; // 啟動定時器 1
PS=1; //設置串口優先級第一
}
void UART_SendByte(unsigned char dat) // 定義串口發送函數
{
SBUF=dat; // 將要發送的數據存入 SBUF
while(!TI); // 等待數據發送完成
TI=0; // 清除發送標志位
}
unsigned char UART_ReceiveByte() // 定義串口接收函數
{
while(!RI); // 等待數據接收完成
RI=0; // 清除接收標志位
return SBUF; // 返回接收到的數據
}
// 從ADC讀取數據的函數
uchar ADC_read_data(unsigned char channel)
{
unsigned char i = 0;
unsigned char j;
unsigned int dat = 0;
unsigned char ndat = 0;
if (channel == 0) channel = 2;//通道1
if (channel == 1) channel = 3;//通道2
ADDI = 1;//輸入引腳拉高
_nop_();//延時1us
_nop_();//延時1us
ADCS = 0;//片選
_nop_();//延時1us
_nop_();//延時1us
ADCLK = 1;//拉高時鐘
_nop_();//延時1us
_nop_();//延時1us
ADCLK = 0;//拉低時鐘
_nop_();//延時1us
_nop_();//延時1us
ADCLK = 1;//拉高時鐘
ADDI = channel & 0x1;
_nop_();//延時1us
_nop_();//延時1us
ADCLK = 0;//拉低時鐘
_nop_();//延時1us
_nop_();//延時1us
ADCLK = 1;//拉高時鐘
ADDI = (channel >> 1) & 0x1;
_nop_();//延時1us
_nop_();//延時1us
ADCLK = 0;//拉低時鐘
ADDI = 1;//輸出1
_nop_();//延時1us
_nop_();//延時1us
dat = 0; //存儲清零
for (i = 0; i < 8; i++) //循環8次
{
dat |= ADDO;//讀取引腳
ADCLK = 1; //拉高時鐘
_nop_();//延時1us
_nop_();//延時1us
ADCLK = 0;//拉低時鐘
_nop_();//延時1us
_nop_();//延時1us
dat <<= 1;//左移 最低位從外面進去,最高位往左頂依舊是最高位 即0832數據最高位先進去
if (i == 7) dat |= ADDO;//讀取引腳
}
for (i = 0; i < 8; i++)//循環8次
{
j = 0;
j = j | ADDO; //讀取引腳
ADCLK = 1; //拉高時鐘
_nop_();//延時1us
_nop_();//延時1us
ADCLK = 0; //拉低時鐘
_nop_();//延時1us
_nop_();//延時1us
j = j << 7; //左移7位
ndat = ndat | j; //合并數據
if (i < 7) ndat >>= 1;//去掉符號
}
ADCS = 1; //清除片選
ADCLK = 0;//拉低時鐘
ADDO = 1; //輸出1
dat <<= 8;//數據移位
dat |= ndat;//合并數據
return(ndat);
}
void init_timer1()//定時器1的初始化函數
{
TMOD|=0X01; //設置計時器1為工作模式1,計時器0為工作模式1
TH0=0X3c; //設置計時器1的計數器高位為0x3C,讓定時器1產生一個50ms的中斷信號
TL0=0XB0; //設置計時器1的計數器低位為0xB0
ET0=1; //打開定時器1中斷允許
EA=1; //打開總中斷
TR0=1; //打開計時器1,若是定時器0則是TH0\TL0\ET0\TR0\TMOD=0X01
}
void main()
{
uchar i=0;
ld=0;
UART_Init(); // 初始化串口
LCD_Init(); // 初始化LCD
init_timer1();
while (1)
{
pwm=adc/2;
if(i<100) //輸出PWM調光,將一個周期具體化為100等分,從而易得高電平多少分來計算pwm
i++;//不斷自增代表對一個周期100等分中每個等分進行檢查此時是高電平還是低電平。在這100中方波越疏越暗,越密越亮。
else
i=0;
if(i<pwm)
LED=0;
else
LED=1;
}
}
// 串口中斷程序
void SerialInterrupt() interrupt 4 {
if (RI == 1) { // 接收到數據
cmd = SBUF; // 存儲接收到的數據
if(cmd=='0')
{ld=1;}
if(cmd=='1')
{ld=0;}
RI = 0; // 清除接收中斷標志
}
}
//定時器1中斷函數
void Timer1() interrupt 1
{
if(time<8)
time++;
else
{
adc = ADC_read_data(0);//讀取adc值
voltage = adc * 500.0 / 255;//將adc值換算成電壓
LED_buffer1[4] = adc / 100 + '0'; //取adc百位
LED_buffer1[5] = adc % 100 / 10 + '0'; //取adc十位
LED_buffer1[6] = adc % 10 + '0'; //取adc個位
LED_buffer2[8] = voltage / 100 + '0'; //取電壓個位
LED_buffer2[9] = '.';//小數點
LED_buffer2[10] = voltage / 10 % 10 + '0'; //取電壓十分位
LED_buffer2[11] = voltage % 10 + '0'; //取電壓百分位
LCD_ShowString(1, 1, LED_buffer1); //顯示字符串
LCD_ShowString(2, 1, LED_buffer2); //顯示字符串
}
TH0 = 0x3C; // 設置定時器1計數初值,用于控制LED亮度的PWM值
TL0 = 0xB0; // 設置定時器1計數初值,用于控制LED亮度的PWM值
}
|