IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> Tiva单片机——简易示波器(UART串口屏) -> 正文阅读

[嵌入式]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、主程序分享

点这里下载

三、常见问题

1、之前写过类似的测定频率的函数,但是就是不好使。

FPUEnable();
FPULazyStackingEnable();

注意将以上的浮点数和浮点运算使能。
(我个人感觉这里就是玄学,我本人也写过,但没开这个两个使能就是数据乱飞,开了就好使了)

2、接上后屏幕没反应

我使用的是480*320的屏幕,上面自带busy口,用以检测屏幕的串口数据处理是否完成。如果手边没有和我一样的。那就发送语句后加延时。
————做一只萌萌的耗子萌翻世界

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-07-28 07:59:49  更:2021-07-28 08:00:46 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 18:31:48-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码