从零开始学习示波器,从零开始学习示波器视频教学

首页 > 经验 > 作者:YD1662024-03-29 05:37:30

其实本人进入芯片的世界的时间并不长,从接触51单片机到现在还不到一年,所以可以算是小白啦,因为制作时间很短,元器件不是很够用,所以只能做出这个只有初级功能的示波器了,只是菜鸟级程序,不建议大家深入学习,如果是新手有兴趣可以做一个玩一下...…用普通的开发板也可以实现。

好了,废话不多说,基于stm32 的微型掌上示波器——这个小作品是我几周业余嵌入式技术课的作品。

废话不多说先上实物图:

从零开始学习示波器,从零开始学习示波器视频教学(1)

黑色一个独立按键是增加网格时间间隔的(后来又加了个独立按键减少网格时间间隔);

蓝色按钮是用来暂停波形的,方便观察;

再右边那两个插针是信号输入的GND和SIGNAL端;

通过独立按键控制发出正弦波、矩形波、三角波、锯齿波、梯形波。

三角波

如上图,这个作品使用4.0寸液晶显示屏来做显示的(上图左边),而芯片是用STM32F103C8T6这一款便价STM32来做的(上图右边)。芯片是做好了的最好系统板,在某宝上网购回来的,好像二十多的样子(不算运费)。

正弦波

从零开始学习示波器,从零开始学习示波器视频教学(2)

梯形波

从零开始学习示波器,从零开始学习示波器视频教学(3)

锯齿波

从零开始学习示波器,从零开始学习示波器视频教学(4)

51单片机开发板做成信号源

从零开始学习示波器,从零开始学习示波器视频教学(5)

洞洞板背面(黑色的是电池盒,带电源开关)

从零开始学习示波器,从零开始学习示波器视频教学(6)

然后板子使用洞洞板来做的,洞洞板就避免不了飞线,所以我用一块海绵封住背面的飞线,声称是为了防止灰尘干扰电路(其实是为了遮盖惨不忍睹的飞线工艺啦{:12:}{:12:})。

好了就写到这里啦,大家有什么想法或者建议,请给我留言我们一同学习啊

项目参考C语言源代码如下:

/* includes ------------------------------------------------------------------*/

#include "stm32f10x_lib.h"

/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/

#define DAC1_DHR8R1_Address 0x40007408

/* Init Structure definition */

DAC_InitTypeDef DAC_InitStructure;

DMA_InitTypeDef DMA_InitStructure;

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

/* Private macro -------------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/

ErrorStatus HSEStartUpStatus;

uc16 Sine12bit[32] = {2047, 2447, 2831, 3185, 3498, 3750, 3939, 4056, 4095, 4056,

3939, 3750, 3495, 3185, 2831, 2447, 2047, 1647, 1263, 909,

599, 344, 155, 38, 0, 38, 155, 344, 599, 909, 1263, 1647};

u32 DualSine12bit[32];

u8 Idx = 0;

/* Private function prototypes -----------------------------------------------*/

void RCC_Configuration(void);

void GPIO_Configuration(void);

void NVIC_Configuration(void);

void Delay(vu32 nCount);

/* Private functions ---------------------------------------------------------*/

/*******************************************************************************

* Function Name : main

* Description : Main program.

* Input : None

* Output : None

* Return : None

*******************************************************************************/

int main(void)

{

#ifdef DEBUG

debug();

#endif

/* System Clocks Configuration */

RCC_Configuration();

/* GPIO configuration */

GPIO_Configuration();

/* NVIC Configuration */

NVIC_Configuration();

/* TIM8 Configuration */

/* Time base configuration */

TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);

TIM_TimeBaseStructure.TIM_Period = 0x19;

TIM_TimeBaseStructure.TIM_Prescaler = 0x00;

TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure);

/* TIM8 TRGO selection */

TIM_SelectOutputTrigger(TIM6, TIM_TRGOSource_Update);

/* DAC channel1 Configuration */

DAC_InitStructure.DAC_Trigger = DAC_Trigger_T6_TRGO;

DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;

DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable;

DAC_Init(DAC_Channel_1, &DAC_InitStructure);

/* DAC channel2 Configuration

DAC_Init(DAC_Channel_2, &DAC_InitStructure); */

/* Fill Sine32bit table */

for (Idx= 0; Idx<32; Idx )

{

DualSine12bit[Idx] = (Sine12bit[Idx] << 16) (Sine12bit[Idx]);

}

/* DMA2 channel4 configuration */

DMA_DeInit(DMA1_Channel3); //将dma的通道寄存器设为默认值

DMA_InitStructure.DMA_PeripheralBaseAddr = DAC1_DHR8R1_Address; //定义dma外设计地址

DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&DualSine12bit;

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //外设作为数据传输的目的地

DMA_InitStructure.DMA_BufferSize = 32; //dma缓存大小

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器不变

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址寄存器 递增

DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; //外设数据宽度

DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;

DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //工作在循环缓存模式,数据传输数目为0时,自动恢复配置初值

DMA_InitStructure.DMA_Priority = DMA_Priority_High;

DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //通道未被设置成内存到内存模式,与循环模式相对

DMA_Init(DMA1_Channel3, &DMA_InitStructure); //将DMA_InitStructure中指定的参数初始化dma的通道寄存器

/* Enable DMA2 Channel4 */

DMA_Cmd(DMA1_Channel3, ENABLE); //使能通道

/* Enable DAC Channel1 */

DAC_Cmd(DAC_Channel_1, ENABLE);

/* Enable DAC Channel2 */

DAC_Cmd(DAC_Channel_1, ENABLE);

/* Enable DMA for DAC Channel2 */

DAC_DMACmd(DAC_Channel_1, ENABLE);

/* TIM8 enable counter */

TIM_Cmd(TIM6, ENABLE);

while (1)

{

GPIO_ResetBits(GPIOA , GPIO_Pin_10);

}

}

/*******************************************************************************

* Function Name : RCC_Configuration

* Description : Configures the different system clocks.

* Input : None

* Output : None

* Return : None

*******************************************************************************/

void RCC_Configuration(void)

{

/* RCC system reset(for debug purpose) */

RCC_DeInit();

/* Enable HSE */

RCC_HSEConfig(RCC_HSE_ON);

/* Wait till HSE is ready */

HSEStartUpStatus = RCC_WaitForHSEStartUp();

if(HSEStartUpStatus == SUCCESS)

{

/* Enable Prefetch Buffer */

FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

/* Flash 2 wait state */

FLASH_SetLatency(FLASH_Latency_2);

/* HCLK = SYSCLK */

RCC_HCLKConfig(RCC_SYSCLK_Div1);

/* PCLK2 = HCLK */

RCC_PCLK2Config(RCC_HCLK_Div1);

/* PCLK1 = HCLK/2 */

RCC_PCLK1Config(RCC_HCLK_Div2);

/* PLLCLK = 8MHz * 9 = 72 MHz */

RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_3);

/* Enable PLL */

RCC_PLLCmd(ENABLE);

/* Wait till PLL is ready */

while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)

{

}

/* Select PLL as system clock source */

RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

/* Wait till PLL is used as system clock source */

while(RCC_GetSYSCLKSource() != 0x08)

{

}

}

/* Enable peripheral clocks --------------------------------------------------*/

/* DMA clock enable */

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

/* AFIO and GPIOA Periph clock enable */

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA, ENABLE);

/* DAC Periph clock enable */

RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);

/* TIM8 Periph clock enable */

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);

}

/*******************************************************************************

* Function Name : GPIO_Configuration

* Description : Configures the different GPIO ports.

* Input : None

* Output : None

* Return : None

*******************************************************************************/

void GPIO_Configuration(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

/* Configure DAC channe1 and DAC channel2 outputs pins */

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5|GPIO_Pin_10;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_Init(GPIOA, &GPIO_InitStructure);

}

/*******************************************************************************

* Function Name : NVIC_Configuration

* Description : Configures Vector Table base location.

* Input : None

* Output : None

* Return : None

*******************************************************************************/

void NVIC_Configuration(void)

{

#ifdef VECT_TAB_RAM

/* Set the Vector Table base location at 0x20000000 */

NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);

#else /* VECT_TAB_FLASH */

/* Set the Vector Table base location at 0x08000000 */

NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);

#endif

}

/*******************************************************************************

* Function Name : Delay

* Description : Inserts a delay time.

* Input : nCount: specifies the delay time length.

* Output : None

* Return : None

*******************************************************************************/

void Delay(vu32 nCount)

{

for(; nCount != 0; nCount--);

}

#ifdef DEBUG

/*******************************************************************************

* Function Name : assert_failed

* Description : Reports the name of the source file and the source line number

* where the assert_param error has occurred.

* Input : - file: pointer to the source file name

* - line: assert_param error line source number

* Output : None

* Return : None

*******************************************************************************/

void assert_failed(u8* file, u32 line)

{

/* User can add his own implementation to report the file name and line number,

ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

/* Infinite loop */

while (1)

{

}

}

#endif

#include"tft3.5.h"

#include "stm32f10x_gpio.h"

//#include"陈锦熙.h"

//#include "美女.h"

//#include "8x16.h"

//#include "GB3231.h"

/*------------------------------------------------

清屏函数

------------------------------------------------*/

void ClearScreen(unsigned int bColor)

{

unsigned int i,j;

LCD_SetPos(0,320,0,480);//

for (i=0;i<480;i )

{

for (j=0;j<320;j )

Write_Data_U16(bColor);

}

}

/*-----------------------------------------------------------------------

写8x16点阵格式的字符

-----------------------------------------------------------------------*/

#include "8x16.h"

void LCD_Putchar8x16(unsigned short x, unsigned short y, char c, unsigned int fColor, unsigned int bColor)

{

unsigned int i,j;

LCD_SetPos(x,x 8-1,y,y 16-1);

for(i=0; i<16;i ) {

unsigned char m=Font8x16[c*16 i];

for(j=0;j<8;j ) {

if((m&0x80)==0x80) {

Write_Data_U16(fColor);

}

else {

Write_Data_U16(bColor);

}

m<<=1;

}

}

}

/*-----------------------------------------------------------------------

写字符

-----------------------------------------------------------------------*/

void LCD_PutChar(unsigned short x, unsigned short y, char c, unsigned int fColor, unsigned int bColor) {

LCD_PutChar8x16( x, y, c, fColor, bColor );

}

#include "GB1616.h" //16*16汉字字模

void PutGB1616(unsigned short x, unsigned short y, unsigned char c[2], unsigned int fColor,unsigned int bColor){

unsigned int i,j,k;

LCD_SetPos(x, x 16-1,y, y 16-1);

for (k=0;k<64;k ) { //64表示自建汉字库中的个数,循环查询内码

if ((codeGB_16[k].Index[0]==c[0])&&(codeGB_16[k].Index[1]==c[1])){

for(i=0;i<32;i ) {

unsigned short m=codeGB_16[k].Msk[i];

for(j=0;j<8;j ) {

if((m&0x80)==0x80) {

Write_Data_U16(fColor);

}

else {

Write_Data_U16(bColor);

}

m<<=1;

}

}

}

}

}

/*-----------------------------------------------------------------------

写字符串

-----------------------------------------------------------------------*/

void LCD_PutString(unsigned short x, unsigned short y, unsigned char *s, unsigned int fColor, unsigned int bColor) {

unsigned char l=0;

while(*s) {

if( *s < 0x80)

{

LCD_PutChar(x l*8,y,*s,fColor,bColor);

s ;l ;

}

else

{

PutGB1616(x l*8,y,(unsigned char*)s,fColor,bColor);

s =2;l =2;

}

}

}

/*-----------------------------------------------------------------------

显示RGB颜色

-----------------------------------------------------------------------*/

void Show_RGB (unsigned int x0,unsigned int x1,unsigned int y0,unsigned int y1,unsigned int Color)

{

unsigned int i,j;

LCD_SetPos(x0,x1,y0,y1);

for (i=y0;i<=y1;i )

{

for (j=x0;j<=x1;j )

Write_Data_U16(Color);

}

}

/*-----------------------------------------------------------------------

显示彩条

-----------------------------------------------------------------------*/

void show_colour_bar (void)

{

int V,H;

LCD_SetPos(0,320,0,480);

for(H=0;H<320;H )

{

for(V=0;V<60;V )

Write_Data_U16(0xf800);

}

for(H=0;H<320;H )

{

for(V=60;V<120;V )

Write_Data_U16(0x07e0);

}

for(H=0;H<320;H )

{

for(V=120;V<180;V )

Write_Data_U16(0x001f);

}

for(H=0;H<320;H )

{

for(V=180;V<240;V )

Write_Data_U16(0xffe0);

}

for(H=0;H<320;H )

{

for(V=240;V<300;V )

Write_Data_U16(0xf81f);

}

for(H=0;H<320;H )

{

for(V=300;V<360;V )

Write_Data_U16(0x07ff);

}

for(H=0;H<320;H )

{

for(V=360;V<420;V )

Write_Data_U16(0xffff);

}

for(H=0;H<320;H )

{

for(V=420;V<480;V )

Write_Data_U16(0x0000);

}

}

/*-----------------------------------------------------------------------

写指令 8位总线

-----------------------------------------------------------------------*/

void LCD_Write_Command(unsigned char u)

{

TFT_CS_SET(0);

TFT_RS_SET(0);

DATAOUT(u);

TFT_WR_SET(0);

TFT_WR_SET(1);

TFT_CS_SET(1);

}

/*-----------------------------------------------------------------------

写数据 8位总线

-----------------------------------------------------------------------*/

void LCD_Write_Data(unsigned char u)

{

TFT_CS_SET(0);

TFT_RS_SET(1);

DATAOUT(u);

TFT_WR_SET(0);

TFT_WR_SET(1);

TFT_CS_SET(1);

}

/*-----------------------------------------------------------------------

写16位数据

-----------------------------------------------------------------------*/

void Write_Data_U16(unsigned int y)

{

unsigned char m,n;

m=y>>8;

n=y;

LCD_Write_Data(m);

LCD_Write_Data(n);

}

/*-----------------------------------------------------------------------

延时程序

-----------------------------------------------------------------------*/

void delayms(unsigned int count)

{

int i,j;

for(i=0;i<count;i )

{

for(j=0;j<26;j );

}

}

/*-----------------------------------------------------------------------

液晶初始化

-----------------------------------------------------------------------*/

void ILI9325_Initial(void)

{

// //液晶接口初始化

// RCC->APB2ENR|=0X0000001C;//先使能外设IO PORTA,B,C时钟

//

// GPIOA->CRL=0X33333333; //PA0-7 推挽输出

// //GPIOA->ODR|=0X00FF;//全部输出高

// GPIOB->CRH=0X33333333; //PB8-15 推挽输出

//GPIOB->ODR|=0X00FF;//全部输出高

/*GPIOB->CRL&=0X000FFFFF;//PB5-7 推挽输出

GPIOB->CRL|=0X33300000;

GPIOB->CRH&=0XFFFFFFF0;//PB8 推挽输出

GPIOB->CRH|=0X00000003;

GPIOB->ODR|=0X01E0;//5-8 输出高

GPIOC->CRL&=0XFF00FFFF;//PC4,5 推挽输出

GPIOC->CRL|=0X00330000;

GPIOC->ODR|=0X0030;//4,5 输出高 */

TFT_RST_SET(0);

delayms(20);

TFT_RST_SET(1);

delayms(200);

// VCI=2.80V

//************* Reset LCD Driver ****************//

// Synchronization after reset

LCD_Write_Command(0xFF);

LCD_Write_Command(0xFF);

delayms(5);

LCD_Write_Command(0xFF);

LCD_Write_Command(0xFF);

LCD_Write_Command(0xFF);

LCD_Write_Command(0xFF);

delayms(10);

LCD_Write_Command(0xB0);

LCD_Write_Data(0x00);

LCD_Write_Command(0x11);

delayms(150);

LCD_Write_Command(0xB3);

LCD_Write_Data(0x02);

LCD_Write_Data(0x00);

LCD_Write_Data(0x00);

LCD_Write_Data(0x00);

LCD_Write_Command(0xC0);

LCD_Write_Data(0x13);

LCD_Write_Data(0x3B);//480

LCD_Write_Data(0x00);

LCD_Write_Data(0x02);

LCD_Write_Data(0x00);

LCD_Write_Data(0x01);

LCD_Write_Data(0x00);//NW

LCD_Write_Data(0x43);

LCD_Write_Command(0xC1);

LCD_Write_Data(0x08);

LCD_Write_Data(0x16);//CLOCK

LCD_Write_Data(0x08);

LCD_Write_Data(0x08);

LCD_Write_Command(0xC4);

LCD_Write_Data(0x11);

LCD_Write_Data(0x07);

LCD_Write_Data(0x03);

LCD_Write_Data(0x03);

LCD_Write_Command(0xC6);

LCD_Write_Data(0x00);

LCD_Write_Command(0xC8);//GAMMA

LCD_Write_Data(0x03);

LCD_Write_Data(0x03);

LCD_Write_Data(0x13);

LCD_Write_Data(0x5C);

LCD_Write_Data(0x03);

LCD_Write_Data(0x07);

LCD_Write_Data(0x14);

LCD_Write_Data(0x08);

LCD_Write_Data(0x00);

LCD_Write_Data(0x21);

LCD_Write_Data(0x08);

LCD_Write_Data(0x14);

LCD_Write_Data(0x07);

LCD_Write_Data(0x53);

LCD_Write_Data(0x0C);

LCD_Write_Data(0x13);

LCD_Write_Data(0x03);

LCD_Write_Data(0x03);

LCD_Write_Data(0x21);

LCD_Write_Data(0x00);

LCD_Write_Command(0x35);

LCD_Write_Data(0x00);

LCD_Write_Command(0x36);

LCD_Write_Data(0x00);

LCD_Write_Command(0x3A);

LCD_Write_Data(0x55);

LCD_Write_Command(0x44);

LCD_Write_Data(0x00);

LCD_Write_Data(0x01);

LCD_Write_Command(0xD0);

LCD_Write_Data(0x07);

LCD_Write_Data(0x07);//VCI1

LCD_Write_Data(0x1D);//VRH

LCD_Write_Data(0x03);//BT

LCD_Write_Command(0xD1);

LCD_Write_Data(0x03);

LCD_Write_Data(0x30);//VCM

LCD_Write_Data(0x10);//VDV

LCD_Write_Command(0xD2);

LCD_Write_Data(0x03);

LCD_Write_Data(0x14);

LCD_Write_Data(0x04);

LCD_Write_Command(0x29);

delayms(30);

LCD_Write_Command(0x2A);

LCD_Write_Data(0x00);

LCD_Write_Data(0x00);

LCD_Write_Data(0x01);

LCD_Write_Data(0x3F);//320

LCD_Write_Command(0x2B);

LCD_Write_Data(0x00);

LCD_Write_Data(0x00);

LCD_Write_Data(0x01);

LCD_Write_Data(0xDF);//480

LCD_Write_Command(0xB4);

LCD_Write_Data(0x00);

delayms(100);

LCD_Write_Command(0x2C);

// Write_Cmd_Data(0x0022);//

}

/*-----------------------------------------------------------------------

设置坐标点

-----------------------------------------------------------------------*/

static void LCD_SetPos(unsigned int x0,unsigned int x1,unsigned int y0,unsigned int y1)

{

LCD_Write_Command(0x2A);

Write_Data_U16(x0);

Write_Data_U16(x1);

//LCD_Write_Data(x0>>8);

//LCD_Write_Data(x0);

//LCD_Write_Data(x1>>8);

//LCD_Write_Data(x1);

LCD_Write_Command(0x2B);

Write_Data_U16(y0);

Write_Data_U16(y1);

//LCD_Write_Data(y0>>8);

//LCD_Write_Data(y0);

//LCD_Write_Data(y1>>8);

//LCD_Write_Data(y1);

LCD_Write_Command(0x2C);

}

//void show_photo(unsigned int x0,unsigned int x1,unsigned int y0,unsigned int y1)

//{

// unsigned int x,y; //定义液晶屏坐标

//

// LCD_SetPos(x0,x1-1,y0,y1-1); //必须x1-1 y1-1

// for(y=y0;y<y1;y ) //是否写完图片数据?

// for(x=x0;x<x1;x )

// {

// LCD_Write_Data(pic[2*((x1-x0)*y x) 1]);

// LCD_Write_Data(pic[2*((x1-x0)*y x)]);

// //Write_Data_U16(0x0f0f);

// } //检测是否写到屏的边缘 160x120 其他尺寸图片请自行更改尺寸

//

//}

void draw_point(unsigned int x0,unsigned int y0,unsigned int wcolor)

{

unsigned int x,y; //定义液晶屏坐标

LCD_SetPos(x0,x0 1,y0,y0 1); //必须x1-1 y1-1

for(y=y0;y<y0 1;y ) //是否写完图片数据?

for(x=x0;x<x0 1;x )

{

Write_Data_U16(wcolor); //16位颜色

// LCD_Write_Data(pic[2*((x1-x0)*y x) 1]); //每个格子的颜色分开了两个8进制表示

// LCD_Write_Data(pic[2*((x1-x0)*y x)]);

//Write_Data_U16(0x0f0f);

} //检测是否写到屏的边缘 160x120 其他尺寸图片请自行更改尺寸

}

最后,如果有什么意见或者建议欢迎您留言给我,让我们共同学习一起进步,

如果需要 程序完整源代码和 设计文件,请在下方留言或者私信我,看到后会第一时间回复。

谢谢!

栏目热文

文档排行

本站推荐

Copyright © 2018 - 2021 www.yd166.com., All Rights Reserved.