【演示版(非完全版)】基于STM32的示波器 V0.9 TFT版
本发布为演示版!!!!!!未加入频率计算功能和菜单功能!http://v.youku.com/v_show/id_XNjE0NjU1NDYw.html
基于ARM Cortex-M3架构的STM32F103VET6,主频72MHz,TFT控制方式为FSMC,刷屏速度比Arduino Mega快n倍!
main.c代码如下:(Keil4工程在下方附件)
#include "stm32f10x.h" //声明STM32 ARM单片机核心库
#include "stm32f10x_easy.h"
#include "LED.h"
#include "delay.h"
#include "RCC.h"
#include "ILI9325.h"
#define TOP 22
#define BUTTON 217
#define LEFT 4
#define RIGHT 315
#define V_CENTER 159
#define H_CENTER 119
void setup(void); //定义类Arduino结构体
void loop(void);
void ADCSet(void); //初始化ADC函数
u16 Get_Adc(u8 ch); //读ADC函数
void drawwavegrid(void); //定义画网格函数
void drawwave(void); //定义画波形函数
void ClearWaveData(void); //定义清空数组函数
void CalcWave(void); //定义计算参数函数
int p;
float gx,gy;
int x,y;
int adcwavedata; //从ADC直接采集的数据
int wavedata; //前4个数据为空数据
int aftery;
int scnx;
int voltageint, voltagefloat1, voltagefloat2, voltagefloat3;
int main(void)
{
setup();
while(1)
{
loop();
}
}
void setup(void)
{
//初始化ADC
APB2_Clock_On(RCC_APB2Periph_ADC1);
GPIOSet(PA,_0,AIN,S_50M);
//DMASet(DMA1_Channel1,ADC1_DR_Address,currentwave,DMA_DIR_PeripheralSRC,1,DMA_PeripheralInc_Disable,DMA_MemoryInc_Disable,DMA_PeripheralDataSize_HalfWord,DMA_MemoryDataSize_HalfWord,DMA_Mode_Circular,DMA_Priority_High,DMA_M2M_Disable); //初始化DMA控制器
ADCSet();
//初始化液晶屏
LCDILI9325_Init();
LCD_Clear(BLACK);
GUI_Text(16,4,"APE STM32 Oscilloscope TFT Mode V1.0",36,YELLOW,BLACK);
GUI_Text(LEFT,BUTTON + 2,"Voltage: V",16,YELLOW,BLACK);
GUI_Text(V_CENTER,BUTTON + 2,"Freq: Hz",15,YELLOW,BLACK);
drawwavegrid();
ClearWaveData();
}
void loop(void)
{
for(p = 0;p < 316;p++)
{
adcwavedata = Get_Adc(0);
}
for(p = 0;p < 316;p++)
{
wavedata = map(adcwavedata,0,4095,216,23);
}
drawwave();
drawwavegrid();
CalcWave();
}
void drawwavegrid(void)
{
GUI_Line(V_CENTER, TOP, V_CENTER, BUTTON, YELLOW);
GUI_Line(LEFT, H_CENTER, RIGHT, H_CENTER, YELLOW);
GUI_Rectangle(LEFT, TOP, RIGHT, BUTTON, YELLOW, BLACK);
for(gx = LEFT;gx < RIGHT;gx += 31.1)
{
for(gy = TOP;gy < BUTTON;gy += 5)
{
LCD_SetPoint(gx,gy,YELLOW);
}
}
for(gx = LEFT;gx < RIGHT;gx += 5)
{
for(gy = TOP;gy < BUTTON;gy += 24.375)
{
LCD_SetPoint(gx,gy,YELLOW);
}
}
}
void drawwave(void)
{
for(x = LEFT + 1;x < RIGHT;x++)
{
LCD_SetPoint(x,wavedata,GREEN);
if(x > 5)
{
GUI_Line(x - 1,aftery,x,wavedata,GREEN);
}
aftery = wavedata;
delay_us(150);
}
for(x = LEFT + 1;x < RIGHT;x++)
{
LCD_SetPoint(x,wavedata,BLACK);
if(x > 5)
{
GUI_Line(x - 1,aftery,x,wavedata,BLACK);
}
aftery = wavedata;
delay_us(150);
}
}
void ClearWaveData(void)
{
for(p = 0;p < 316;p++)
{
wavedata = 0;
}
}
void CalcWave(void)
{
float voltage;//,freq;
long voltagecalc;//,freqcalc;
voltagecalc = 0;//freqcalc = 0;
for(scnx = LEFT + 1;scnx < RIGHT;scnx++)
{
voltagecalc += adcwavedata;
}
voltagecalc = voltagecalc / 309;
voltage = mapfloat(voltagecalc,0,4095,0,3.3);
voltageint = voltage; //强制取整
voltagefloat1 = (voltage - (int)voltage) * 1000 / 100; //保留三位小数(第一位)
voltagefloat2 = (voltage - (int)voltage) * 1000 / 10; //保留三位小数(第二位)
voltagefloat2 = voltagefloat2 % 10;
voltagefloat3 = (voltage - (int)voltage) * 1000; //保留三位小数(第三位)
voltagefloat3 = voltagefloat3 % 10;
LCD_PutNum(70,BUTTON + 2,voltageint,YELLOW);
LCD_PutChar(79,BUTTON + 2,'.',YELLOW,BLACK);
LCD_PutNum(89, BUTTON + 2,voltagefloat1,YELLOW);
LCD_PutNum(99, BUTTON + 2,voltagefloat2,YELLOW);
LCD_PutNum(109,BUTTON + 2,voltagefloat3,YELLOW);
}
void ADCSet(void)
{
//通道10/11设置
RCC->APB2ENR|=1<<9; //ADC1时钟使能
RCC->APB2RSTR|=1<<9; //ADC1复位
RCC->APB2RSTR&=~(1<<9);//复位结束
RCC->CFGR&=~(3<<14); //分频因子清零
//SYSCLK/DIV2=12M ADC时钟设置为12M,ADC最大时钟不能超过14M!
//否则将导致ADC准确度下降!
RCC->CFGR|=2<<14;
ADC1->CR1&=0XF0FFFF; //工作模式清零
ADC1->CR1|=0<<16; //独立工作模式
ADC1->CR1&=~(1<<8); //非扫描模式
ADC1->CR2&=~(1<<1); //单次转换模式
ADC1->CR2&=~(7<<17);
ADC1->CR2|=7<<17; //软件控制转换
ADC1->CR2|=1<<20; //使用用外部触发(SWSTART)!!! 必须使用一个事件来触发
ADC1->CR2&=~(1<<11); //右对齐
ADC1->SQR1&=~(0XF<<20);
ADC1->SQR1&=0<<20; //1个转换在规则序列中也就是只转换规则序列1
//设置通道0~3的采样时间
ADC1->SMPR2&=0XFFFFF000;//通道0,1,2,3采样时间清空
ADC1->SMPR2|=7<<9; //通道3 239.5周期,提高采样时间可以提高精确度
ADC1->SMPR2|=7<<6; //通道2 239.5周期,提高采样时间可以提高精确度
ADC1->SMPR2|=7<<3; //通道1 239.5周期,提高采样时间可以提高精确度
ADC1->SMPR2|=7<<0; //通道0 239.5周期,提高采样时间可以提高精确度
ADC1->CR2|=1<<0; //开启AD转换器
ADC1->CR2|=1<<3; //使能复位校准
while(ADC1->CR2&1<<3); //等待校准结束
//该位由软件设置并由硬件清除。在校准寄存器被初始化后该位将被清除。
ADC1->CR2|=1<<2; //开启AD校准
while(ADC1->CR2&1<<2); //等待校准结束
//该位由软件设置以开始校准,并在校准结束时由硬件清除
}
u16 Get_Adc(u8 ch)
{
//设置转换序列
ADC1->SQR3&=0XFFFFFFE0;//规则序列1 通道ch
ADC1->SQR3|=ch;
ADC1->CR2|=1<<22; //启动规则转换通道
while(!(ADC1->SR&1<<1));//等待转换结束
return ADC1->DR; //返回adc值
}
TFT接线方式见\\Libraries\LCDdriver(独立使用)\fsmc.h 真的很棒,在下佩服的五体投地 新手,俺有ILI9320的2.4屏,还有SSD1289的4.3屏,驱动咋修改啊,请指导下 学习学习支持支持 感谢大神分享,正需要! 采样率有点低:lol
页:
[1]