创意发明:基于stm32的微型掌上示波器 设计说明书电路及源代码

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

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

废话不多说先上实物图:
创意发明:基于stm32的微型掌上示波器 设计说明书电路及源代码_第1张图片
黑色一个独立按键是增加网格时间间隔的(后来又加了个独立按键减少网格时间间隔);
蓝色按钮是用来暂停波形的,方便观察;
再右边那两个插针是信号输入的GND和SIGNAL端;
创意发明:基于stm32的微型掌上示波器 设计说明书电路及源代码_第2张图片
三角波

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

创意发明:基于stm32的微型掌上示波器 设计说明书电路及源代码_第3张图片
正弦波

创意发明:基于stm32的微型掌上示波器 设计说明书电路及源代码_第4张图片
梯形波

创意发明:基于stm32的微型掌上示波器 设计说明书电路及源代码_第5张图片
锯齿波

创意发明:基于stm32的微型掌上示波器 设计说明书电路及源代码_第6张图片
51单片机开发板做成信号源

如上图,因为院里面的实验室太远,我就自己用51单片机开发板自己做了个简易函数发生器。通过独立按键控制发出正弦波、矩形波、三角波、锯齿波、梯形波。
其实单片机开发板已经是我的核心家当了!因为我学习ARM的时候并没有买ARM的开发板,而是用51开发板把程序烧录进去ARM芯片里面去……(其实零花钱都用去旅游去了。。。)

创意发明:基于stm32的微型掌上示波器 设计说明书电路及源代码_第7张图片
洞洞板背面(黑色的是电池盒,带电源开关)

然后板子使用洞洞板来做的,洞洞板就避免不了飞线,所以我用一块海绵封住背面的飞线,声称是为了防止灰尘干扰电路(其实是为了遮盖惨不忍睹的飞线工艺啦{: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 {
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 // for(x=x0;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 for(x=x0;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 其他尺寸图片请自行更改尺寸

}

最后,如果有什么意见或者建议欢迎您留言给我,让我们共同学习一起进步,
如果需要 程序完整源代码和 设计文件,请在下方留言或者私信我,看到后会第一时间回复。

谢谢!

你可能感兴趣的:(单片机,编程,UART)