Tiva单片机——简易示波器(UART串口屏)
前言:简易示波器、1MHz以内的频率检测、数据形式的触发、电压值的标定
一、整体介绍
在本次设计中,采用的是TI公司的TivaTM4123GXL系列单片机。本次给大家带来的是简易示波器的一些设计方法和自己的一些见解,希望对大家的学习有所帮助。另外如有错误,还请多多指正。
二、代码的分段解读
1、头函数
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include "inc/tm4c123gh6pm.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_flash.h"
#include "inc/hw_ints.h"
#include "driverlib/sysctl.h"
#include "driverlib/interrupt.h"
#include "driverlib/gpio.h"
#include "driverlib/uart.h"
#include "driverlib/timer.h"
#include "utils/uartstdio.h"
#include "driverlib/systick.h"
#include "driverlib/pin_map.h"
#include "driverlib/adc.h"
#include "inc/hw_adc.h"
#include "assert.h"
#include "driverlib/pwm.h"
#include "driverlib/flash.h"
#include "driverlib/fpu.h"
有缺文件的可以去Ti官网找
2、宏定义及变量定义
#define delay_ms(n); SysCtlDelay(n*(SysCtlClockGet()/3000));//延时函数
//已使用IO口 ADC PE5
// UART(LCD) PB0-RX PB1-TX BUSYCHECK PE4
// F0 PB2
//
//
//屏幕 X479 Y319
//LCD变量
uint32_t LCD_X[2];//X479
uint32_t LCD_Y[2];//Y319
//已使用的引脚
// PE3-2-1-0 PF1-2-3 PB0-1
//状态变量
uint32_t MCUModel; //0待机 1ADC采集 2数据传输 3测频 4测算触发点 5校准模式 6开机模式
uint32_t MCUModel1; //0待机 1ADC采集 2数据传输 3测频暂存
uint32_t UartPlayorStop; //单片机LCD中断处理状态 0串口中断处理完毕1串口中断处理中
uint32_t ADC0WriteorRead=1; //单片机ADC中断处理状态 0 ADC采集完毕 1 ADC采集中 2ADC暂停状态
uint32_t f0Check=0; //频率检测状态位 0未检测,1检测完毕
//数据变量
//ADC数据
int32_t ADC0SignGet[1]={0}; //ADC采样数据存储数组
//UART数据
uint8_t UartDateRead; //单片机UART串口数据读取
uint8_t UartLCDDateReads[20]; //单片机UART串口数据读取数组
uint32_t UartLCDDateReadNum=0; //单片机UART串口数据读取数组位数
//存储数据
uint32_t TriggerCheckPin=1;//未触发显示状态位 0上次未触发 1上次已经触发
uint32_t TriggerCheck=0;//触发位状态 0等待触发 1已经触发
uint32_t TriggerNum=1;//触发位
uint32_t Date[640]={0};//储存数组
uint32_t DateNum=0;//储存数组位数
uint32_t Vtemp=0;//电压值转换临时储存
//暂停
uint32_t StopCheck=0;//暂停检测位0未暂停1暂停中
//时域
float TimeGear[4]={1,2,3,4};//时域挡位
uint32_t TimeGearNum=0;//时域位
uint32_t TimeGearNum1;//时域暂存位
//幅域
float RangeGear[4]={0.25,0.5,1,2};//幅域挡位
uint32_t RangeGearNum=2;//幅域位
uint32_t RangeGearNum1;//幅域暂存位
//V
uint32_t VpporVrmsCheck=0; //V测定状态检测位 0 Vrect-平均值 1 Vrms-有效值(只对正弦波有效)
uint32_t Vmax=0; //峰值
uint32_t VmaxSum=0; //峰值累加
uint32_t Vmin=3300; //谷值
uint32_t VminSum=0; //谷值累加
uint32_t VCheckStand=200; //检测区间
uint32_t VCheckStandNum=0; //幅值检测位数
uint32_t Vrect=0; //幅值检测位数
uint32_t VppCheckNum=0;//幅值计算次数
//频率
unsigned char delay = 200;//累计下降沿次数 去除噪点
unsigned int Frequencecount = 0;//下降沿计数
unsigned char state = 0;//标记一次下降的开始---0 和 下一次下降沿的结束 ---1 之间的间隔即为该信号的周期
unsigned int fre = 0;//记录下降沿开始时的TimerCount
unsigned int temp = 0;//频率测量临时变量
unsigned int Frequence = 0;//频率值
unsigned int FCheck=0;
//校验
uint32_t VCheckNum=0;//校验循环采样数
uint32_t VCheckSum=20;//循环采样次数
uint32_t VCheckAddSum=0;//循环采样数据累加
float VCheckStand075=1;//0.75V标定
float VCheckStand150=1;//1.50V标定
float VCheckStand225=1;//2.25V标定
float VCheckStand300=1;//3.00V标定
uint32_t VCheckS075=0;//0.75V标志位
uint32_t VCheckS150=0;//1.50V标志位
uint32_t VCheckS225=0;//2.25V标志位
uint32_t VCheckS300=0;//3.00V标志位
变量定义就不说太多了
3、外设初始化
void SysCtlPeripheralEnableInt(void)//外设使能以及初始化
{
//状态变量初始化
MCUModel=6;
//LED外设配置
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);//LED IO引脚外设使能
GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3);
//串口屏UART1
IntPrioritySet(INT_UART1, 0);//Uart1中断优先级定义
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1);//UART外设使能
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);//UART IO引脚外设使能
GPIOPinConfigure(GPIO_PB0_U1RX);//配置复用功能 //读取
GPIOPinConfigure(GPIO_PB1_U1TX); //发送
GPIOPinTypeUART(GPIO_PORTB_BASE,GPIO_PIN_0|GPIO_PIN_1);//分配UART信号
//配置UART参数(这样配置可以用UARTprintf)
UARTClockSourceSet(UART1_BASE, UART_CLOCK_PIOSC); //使用16MHz内部高精度振荡器(PIOSC)作为UART模块时钟
UARTStdioConfig(1,115200, 16000000); //UART编号、波特率、UART时钟频率(频率要和上一行设的一致)
//FIFO配置
//UARTFIFOLevelSet(UART1_BASE,UART_FIFO_TX1_8,UART_FIFO_RX1_8); //FIFO填入半满(1/8 2byte)时触发中断
//UARTFIFOEnable(UART1_BASE);
IntEnable(INT_UART1); //enable the UART interrupt
UARTIntEnable(UART1_BASE, UART_INT_RX | UART_INT_RT); //only enable RX and TX interrupts
UARTIntRegister(UART1_BASE,UARTIntHandler);//注册中断服务函数
//UARTprintf("CLS(0);\r\n");//清屏
//LCD繁忙检测
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);//LED IO引脚外设使能
GPIODirModeSet(GPIO_PORTE_BASE, GPIO_PIN_4, GPIO_DIR_MODE_IN); //设置PE4为输入.
GPIOPadConfigSet(GPIO_PORTE_BASE, GPIO_PIN_4, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU); //方向为输入 推挽上拉
LCD_Open_int();
delay_ms(1000);
MCUModel=5;
LCD_Check_int();
//ADC0
IntPrioritySet(INT_ADC0SS3, 2);//ADC0中断优先级定义
SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);//ADC0外设使能
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);//使能配置ADC0IO引脚PE5
GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_5);//配置ADC0IO引脚PE5
//序列发生器 | 采样数 | FIFO深度
// SS3 | 1 | 1
ADCSequenceConfigure(ADC0_BASE, 3, ADC_TRIGGER_ALWAYS, 0);
ADCSequenceStepConfigure(ADC0_BASE, 3, 0, ADC_CTL_CH8 | ADC_CTL_IE | ADC_CTL_END);// 启用ADC0序列0中断
ADCIntRegister(ADC0_BASE ,3, ADC0Sequence0Handler);// 启用ADC0中断头文件
//ADCIntEnable(ADC0_BASE, 3);//ADC0初始化使能
IntEnable(INT_ADC0SS3);
ADCSequenceEnable(ADC0_BASE, 3);// 使能采样序列
//pwm PB4
//配置PWM时钟(设置USEPWMDIV分频器)
SysCtlPWMClockSet(SYSCTL_PWMDIV_1);
//使能时钟
SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM1); //使能PWM模块1时钟
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); //使能GPIOF时钟
//使能引脚复用PWM功能
GPIOPinTypePWM(GPIO_PORTF_BASE,GPIO_PIN_2);
//GPIOPinTypePWM(GPIO_PORTF_BASE,GPIO_PIN_3);
//PWM信号分配
GPIOPinConfigure(GPIO_PF2_M1PWM6); //PF2->PWM模块1信号6
//GPIOPinConfigure(GPIO_PF3_M1PWM7); //PF3->PWM模块1信号7
//配置PWM发生器
//模块1->发生器3->上下计数,不同步
PWMGenConfigure(PWM1_BASE,PWM_GEN_3,PWM_GEN_MODE_UP_DOWN|PWM_GEN_MODE_NO_SYNC);
//配置PWM周期
PWMGenPeriodSet(PWM1_BASE,PWM_GEN_3,10000); //64*10^3/16/10^6=4ms 4000000
//配置PWM占空比
PWMPulseWidthSet(PWM1_BASE,PWM_OUT_6,PWMGenPeriodGet(PWM1_BASE, PWM_GEN_3)*0.5); //比较值为四分之一总计数值,25%
//PWMPulseWidthSet(PWM1_BASE,PWM_OUT_7,PWMGenPeriodGet(PWM1_BASE, PWM_GEN_3)*0.01); //比较值为四分之三总计数值,75%
//使能PWM模块1输出
PWMOutputState(PWM1_BASE,PWM_OUT_6_BIT,true);
//PWMOutputState(PWM1_BASE,PWM_OUT_7_BIT,true);
//使能PWM发生器
PWMGenEnable(PWM1_BASE,PWM_GEN_3);
IntPrioritySet(INT_TIMER3A, 1);//TIMERA中断优先级定义
SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER3);//使能配置TIMERA定时器
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
GPIOPinTypeGPIOInput(GPIO_PORTB_BASE, GPIO_PIN_2);
GPIOPinTypeTimer(GPIO_PORTB_BASE, GPIO_PIN_2);
GPIOPinConfigure(GPIO_PB2_T3CCP0);
TimerConfigure(TIMER3_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_CAP_TIME_UP);
TimerControlEvent(TIMER3_BASE, TIMER_A, TIMER_EVENT_NEG_EDGE);
TimerIntRegister(TIMER3_BASE, TIMER_A, FrequentHandler);
IntMasterEnable();
TimerIntEnable(TIMER3_BASE, TIMER_CAPA_EVENT);
IntEnable(INT_TIMER3A);//使能定时器模块Timer0的定时器A的中断。
}
这里的PWM生成是为了随手进行示波器的测试(就不用测试都需要示波器)
4、波形触发设计
if(MCUModel==4)
{
if(TriggerCheck!=1)
{
if( (Date[TriggerNum-1]<Date[TriggerNum])&&Date[TriggerNum]>=1861)//1861*3300/4095 1500m
{
TriggerCheckPin=1;
TriggerCheck=1;
LCD_X[1]=53;
Vtemp=Date[TriggerNum]*(155/4095.0)*RangeGear[RangeGearNum];
LCD_Y[1]=227+75*(RangeGear[RangeGearNum]-1)-Vtemp;//PE1;
MCUModel=3;
if(VpporVrmsCheck==0)
{
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("DS16(250,256,'Vrect:',4,0);\r\n");
}
else
{
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("DS16(250,256,'000000',8,0);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("DS16(250,256,'Vrms:',4,0);\r\n");
}
}
else
{
if(TriggerNum>600)
{
TriggerNum=1;
MCUModel=1;
if(TriggerCheckPin==1)
{
TriggerCheckPin=0;
ClearP(51,71,349,229);
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("DS16(90,140,'未找到触发点,正在等待触发···',4,0);\r\n");
ClearP(175, 257,245,280);
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("DS16(175,257,'----Hz',4,0);\r\n");
ClearP(98,257,145,280);
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("DS16(95,257,'----mV',4,0);\r\n");
ClearP(300,257,345,280);
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("DS16(300,257,'----mV',4,0);\r\n");
}
delay_ms(10);
ADCIntEnable(ADC0_BASE,3);
//TimerEnable(TIMER0_BASE,TIMER_A);//使能定时器TimerA。
}
else TriggerNum++;
}
}
}
第五行判断里的<号为上升沿的意思,改为>号,即为下降沿。后面的数据1861为1500mV根据3300/4095转换出来的数据,更改数据即为改变触发电平。(我这里的代码翻译过来就是在1.5且处于上升沿时触发波形显示)
5、电压标定设计
if(MCUModel==5)
{
if(ADC0WriteorRead==0&&VCheckS075==1) //750mV校准
{
ADC0WriteorRead=1;
if(700<(ADC0SignGet[0]*3300/4095.0)&&(ADC0SignGet[0]*3300/4095.0)<800)
{
VCheckNum++;
VCheckAddSum=ADC0SignGet[0]+VCheckAddSum;
if(VCheckNum==VCheckSum)
{
VCheckStand075=18613.63636/(1.0*VCheckAddSum);
VCheckS075=0;
VCheckNum=0;
VCheckAddSum=0;
ADCIntDisable(ADC0_BASE, 3);
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("DS12(300,260,'标定完成',4,0);\r\n");
}
}
}
if(ADC0WriteorRead==0&&VCheckS150==1)//1500mV校准
{
ADC0WriteorRead=1;
if(1450<(ADC0SignGet[0]*3300/4095.0)&&(ADC0SignGet[0]*3300/4095.0)<1550)
{
VCheckNum++;
VCheckAddSum=ADC0SignGet[0]+VCheckAddSum;
if(VCheckNum==VCheckSum)
{
VCheckStand150=37227.27273/(1.0*VCheckAddSum);
VCheckS150=0;
VCheckNum=0;
VCheckAddSum=0;
ADCIntDisable(ADC0_BASE, 3);
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("DS12(300,260,'标定完成',4,0);\r\n");
}
}
}
if(ADC0WriteorRead==0&&VCheckS225==1)//2250mV校准
{
ADC0WriteorRead=1;
if(2200<(ADC0SignGet[0]*3300/4095.0)&&(ADC0SignGet[0]*3300/4095.0)<2300)
{
VCheckNum++;
VCheckAddSum=ADC0SignGet[0]+VCheckAddSum;
if(VCheckNum==VCheckSum)
{
VCheckStand225=55840.90909/(1.0*VCheckAddSum);
VCheckS225=0;
VCheckNum=0;
VCheckAddSum=0;
ADCIntDisable(ADC0_BASE, 3);
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("DS12(300,260,'标定完成',4,0);\r\n");
}
}
}
if(ADC0WriteorRead==0&&VCheckS300==1)//3000mV校准
{
ADC0WriteorRead=1;
if(2950<(ADC0SignGet[0]*3300/4095.0)&&(ADC0SignGet[0]*3300/4095.0)<3050)
{
VCheckNum++;
VCheckAddSum=ADC0SignGet[0]+VCheckAddSum;
if(VCheckNum==VCheckSum)
{
VCheckStand300=74454.54545/(1.0*VCheckAddSum);
VCheckS300=0;
VCheckNum=0;
VCheckAddSum=0;
ADCIntDisable(ADC0_BASE, 3);
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("DS12(300,260,'标定完成',4,0);\r\n");
}
}
}
}
这里设计了四个电压标定值 750mV 1500mV 2500mV 3000mV,VCheckStand075、VCheckStand150、VCheckStand225、VCheckStand300这四个数即为计算出的修正系数,使用时直接乘就行。
6、频率测定(最高到达1MHz)
外设定义详见第三部分的外设初始化
void FrequentHandler()
{
//去除噪声影响
if(Frequencecount<=delay)
Frequencecount++;
else
{
if(state == 0)
{
fre = TimerValueGet(TIMER3_BASE, TIMER_A);
state = 1;
}
else
{
temp = SysCtlClockGet() / ((unsigned int)TimerValueGet(TIMER3_BASE, TIMER_A) - fre);
state = 0;
if( temp > 0.5 )
{
//FCheck=1;
MCUModel=2;
Frequence =temp;
ClearP(175, 257,245,280);
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("DS16(175,257,'%dHz',4,0);\r\n",Frequence);
}
Frequencecount = 0;
}
}
TimerIntClear(TIMER3_BASE,TIMER_CAPA_EVENT); // 清除WTimer0捕获器A的中断标志位
if(MCUModel==2)
{
TimerDisable(TIMER3_BASE, TIMER_A);
}
}
简单来说就是定时器测频率,另外因为去噪声的缘故,频率下限较高
7、采集数据处理
void ADC0Sequence0Handler(void)//ADC中断头文件
{
ADC0WriteorRead=1;//ADC状态
ADCSequenceDataGet(ADC0_BASE, 3, ADC0SignGet); // 读取ADC值
ADC0WriteorRead=0;
if(MCUModel==1)
{
Date[DateNum]=ADC0SignGet[0];
DateNum++;
if(DateNum>=640)
{
//DateNum=0;
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("PL(%d,71,%d,229,8);\r\n",52,52);
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("PL(%d,71,%d,229,8);\r\n",53,53);
MCUModel=4;
DateNum=0;
ADCIntDisable(ADC0_BASE, 3);
}
}
if(MCUModel==5)
{
if(VCheckS075==1&&700<(ADC0SignGet[0]*3300/4095.0)&&(ADC0SignGet[0]*3300/4095.0)<800) //750mV校准
{
VCheckNum++;
VCheckAddSum=ADC0SignGet[0]+VCheckAddSum;
if(VCheckNum==VCheckSum)
{
VCheckStand075=18613.63636/(1.0*VCheckAddSum);
VCheckS075=0;
VCheckNum=0;
VCheckAddSum=0;
ADCIntDisable(ADC0_BASE, 3);
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("DS12(300,260,'标定完成',4,0);\r\n");
}
}
if(VCheckS150==1&&1450<(ADC0SignGet[0]*3300/4095.0)&&(ADC0SignGet[0]*3300/4095.0)<1550)//1500mV校准
{
VCheckNum++;
VCheckAddSum=ADC0SignGet[0]+VCheckAddSum;
if(VCheckNum==VCheckSum)
{
VCheckStand150=37227.27273/(1.0*VCheckAddSum);
VCheckS150=0;
VCheckNum=0;
VCheckAddSum=0;
ADCIntDisable(ADC0_BASE, 3);
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("DS12(300,260,'标定完成',4,0);\r\n");
}
}
if(VCheckS225==1&&2200<(ADC0SignGet[0]*3300/4095.0)&&(ADC0SignGet[0]*3300/4095.0)<2300)//2250mV校准
{
VCheckNum++;
VCheckAddSum=ADC0SignGet[0]+VCheckAddSum;
if(VCheckNum==VCheckSum)
{
VCheckStand225=55840.90909/(1.0*VCheckAddSum);
VCheckS225=0;
VCheckNum=0;
VCheckAddSum=0;
ADCIntDisable(ADC0_BASE, 3);
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("DS12(300,260,'标定完成',4,0);\r\n");
}
}
if(VCheckS300==1&&2950<(ADC0SignGet[0]*3300/4095.0)&&(ADC0SignGet[0]*3300/4095.0)<3050)//3000mV校准
{
VCheckNum++;
VCheckAddSum=ADC0SignGet[0]+VCheckAddSum;
if(VCheckNum==VCheckSum)
{
VCheckStand300=74454.54545/(1.0*VCheckAddSum);
VCheckS300=0;
VCheckNum=0;
VCheckAddSum=0;
ADCIntDisable(ADC0_BASE, 3);
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("DS12(300,260,'标定完成',4,0);\r\n");
}
}
}
ADCIntClear(ADC0_BASE, 3); // 清除ADC中断标志。
//_nop();
}
这里涉及到了数据处理,以及多个外设之间的数据传递与协调
8、界面设计(UART串口屏)
8.1、开机界面图形设计
void LCD_Open_int()//开机屏幕处理
{
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("CLS(0);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("PIC(81,112,2);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("DS48(168,128,'Oscilloscope',5,0);\r\n");
}
这里我调用了我的logo,另外有关图片导入的问题,详见GPU使用方法,这里不再详述
8.2、初始界面设计
void LCD_Check_int()//校验屏幕处理
{
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("CLS(0);\r\n");//清屏
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("BOXF(0,0,480,320,8);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("SBC(8);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("DS24(180,25,'示波器校准',15,0);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("BOX(40,60,440,300,13);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("BOX(50,70,350,230,5);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("BOX(50,240,350,290,4);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("BTN(1,355,70,430,100,2);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("BTN(2,355,105,430,135,2);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("BTN(3,355,155,430,185,2);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("BTN(4,355,190,430,220,2);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("BTN(5,355,225,430,255,2);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("BTN(6,355,260,430,290,2);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("DS16(360,75,'执行校验',15,0);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("DS16(360,110,'结束校验',15,0);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("DS16(360,160,'0.75V标定',15,0);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("DS16(360,195,'1.50V标定',15,0);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("DS16(360,230,'2.25V标定',15,0);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("DS16(360,265,'3.00V标定',15,0);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("DS12(60,260,'当前电压标定幅值:',4,0);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("DS12(220,260,'当前标定状态:',4,0);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("DS12(165,260,'-----',4,0);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("DS12(300,260,'-----',4,0);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("BS12(60,75,345,5,' 欢迎使用本示波器,本示波器采用TI出品的EK-TM4C123GXL作为主控。',5);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("BS12(60,110,345,5,' 波形最高频率可显示到20kHz,频率、峰峰值、以及平均值的测算最高可以满足1MHz。',5);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("BS12(60,145,345,5,' 内置数字触发,为1.5V上升沿触发,同时具备时轴展宽、缩减,幅轴展宽、缩减的功能。',5);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("BS12(60,180,345,5,' 示波器频率测量误差为1%%(10Hz~1MHz),峰峰值测量误差为2%%(1Hz~1MHz)',5);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("BS12(60,210,345,5,' -----开发者G 2021年6月4号',5);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("DS12(40,305,'具体详情请访问网址:https://blog.csdn.net/qq_15038387/article/details/119142364?spm=1001.2014.3001.5501',7,0);\r\n");
}
这里为示波器标定与介绍界面
8.3、示波界面设计
void LCD_int()//工作屏幕处理
{
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("CLS(0);\r\n");//清屏
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("BOXF(0,0,480,320,8);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("SBC(8);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("DS24(180,25,'简易示波器',15,0);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("BOX(40,60,440,300,13);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("BOX(50,70,350,230,5);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("BOX(50,240,350,290,4);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("BTN(1,355,70,430,100,2);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("BTN(2,355,105,430,135,2);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("BTN(3,355,155,430,185,2);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("BTN(4,355,190,430,220,2);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("BTN(5,355,225,430,255,2);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("BTN(6,355,260,430,290,2);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("DS16(360,75,'暂停/运行',15,0);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("DS16(360,110,'电压标定',15,0);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("DS16(360,160,'时轴放大',15,0);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("DS16(360,195,'时轴缩减',15,0);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("DS16(360,230,'幅轴放大',15,0);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("DS16(360,265,'幅轴缩减',15,0);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("DS16(55,256,'Yp-p:',4,0);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("DS16(150,256,'f0:',4,0);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("DS16(250,256,'Vrect:',4,0);\r\n");
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("DS12(40,305,'我已经写在博客里:https://blog.csdn.net/qq_15038387',7,0);\r\n");
}
以上为示波界面设计
8.4、交互按键设计
void LCDstringcheck(void)
{
if(UartLCDDateReads[4]=='1')//2暂停/运行 5执行校验
{
if(MCUModel==2||MCUModel==0)
{
if(StopCheck==0)
{
MCUModel1=MCUModel;
MCUModel=0;
StopCheck=1;
}
else
{
MCUModel=MCUModel1;
StopCheck=0;
}
}
if(MCUModel==5)
{
if((VCheckS075+VCheckS150+VCheckS225+VCheckS300)>=1)
{
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("DS12(300,260,'正在标定',4,0);\r\n");
ADCIntEnable(ADC0_BASE, 3);
}
}
UartLCDDateReads[4]="X";
}
if(UartLCDDateReads[4]=='2')//2电压校验 5结束校验
{
if(MCUModel==5)
{
LCD_int();
MCUModel=1;
TriggerCheckPin=1;
TriggerCheck=0;
ADCIntEnable(ADC0_BASE, 3);
//TimerEnable(TIMER0_BASE,TIMER_A);//使能定时器TimerA。
}
else
{
MCUModel=5;
ADCIntDisable(ADC0_BASE, 3);
//TimerDisable(TIMER0_BASE, TIMER_A);
LCD_Check_int();
}
UartLCDDateReads[4]="X";
}
if(UartLCDDateReads[4]=='3')//2时域放大 5 0.75V标定
{
if(MCUModel==2)
{
if(TimeGearNum<3)
{
TimeGearNum++;//时域位
}
}
if(MCUModel==5)
{
VCheckS075=1;
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("DS12(165,260,'0.75V',4,0);\r\n");
}
UartLCDDateReads[4]="X";
}
if(UartLCDDateReads[4]=='4')//2时域缩减 5 1.50V标定
{
if(MCUModel==2)
{
if(TimeGearNum>0)
{
TimeGearNum--;//时域位
}
}
if(MCUModel==5)
{
VCheckS150=1;
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("DS12(165,260,'1.50V',4,0);\r\n");
}
UartLCDDateReads[4]="X";
}
if(UartLCDDateReads[4]=='5')//2幅域展宽 5 2.25V标定
{
if(MCUModel==2)
{
if(RangeGearNum<3)
{
RangeGearNum++;//时域位
}
}
if(MCUModel==5)
{
VCheckS225=1;
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("DS12(165,260,'2.25V',4,0);\r\n");
}
UartLCDDateReads[4]="X";
}
if(UartLCDDateReads[4]=='6')//2幅域缩减 5 3.00V标定
{
if(MCUModel==2)
{
if(RangeGearNum>0)
{
RangeGearNum--;//时域位
}
}
if(MCUModel==5)
{
VCheckS300=1;
while(GPIOPinRead(GPIO_PORTE_BASE,GPIO_PIN_4)!=0x0);
UARTprintf("DS12(165,260,'3.00V',4,0);\r\n");
}
UartLCDDateReads[4]="X";
}
}
以上是对LCD屏幕热键返回值的处理
9、主程序分享
10、实际运行视频
三、常见问题
1、之前写过类似的测定频率的函数,但是就是不好使。
FPUEnable();
FPULazyStackingEnable();
注意将以上的浮点数和浮点运算使能。
(我个人感觉这里就是玄学,我本人也写过,但没开这个两个使能就是数据乱飞,开了就好使了)
2、接上后屏幕没反应
我使用的是480*320的屏幕,上面自带busy口,用以检测屏幕的串口数据处理是否完成。如果手边没有和我一样的。那就发送语句后加延时。
————做一只萌萌的耗子萌翻世界