0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

基于STM32的波形發(fā)生器設(shè)計(jì)

CHANBAEK ? 來(lái)源:?jiǎn)纹瑱C(jī)資料寶庫(kù) ? 作者: 醉生夢(mèng)死 ? 2023-12-12 15:16 ? 次閱讀

一、項(xiàng)目介紹

信號(hào)發(fā)生器在生產(chǎn)實(shí)踐和科技領(lǐng)域中有著廣泛的應(yīng)用,各種波形曲線均可以用三角函數(shù)方程式來(lái)表示。能夠產(chǎn)生多種波形,如三角波、鋸齒波、矩形波(含方波)、正弦波的電路被稱為函數(shù)信號(hào)發(fā)生器。函數(shù)信號(hào)發(fā)生器在電路實(shí)驗(yàn)和設(shè)備檢測(cè)中具有十分廣泛的用途,例如在通信、廣播、電視系統(tǒng)中,都需要射頻(高頻)發(fā)射。這里的射頻波就是載波,把音頻(低頻)、視頻信號(hào)或脈沖信號(hào)運(yùn)載出去,就需要能夠產(chǎn)生高頻的振蕩器。在工業(yè)、農(nóng)業(yè)、生物醫(yī)學(xué)等領(lǐng)域內(nèi),如高頻感應(yīng)加熱、熔煉、淬火、超聲診斷、核磁共振成像等,都需要功率或大或小、頻率或高或低的振蕩器。函數(shù)信號(hào)發(fā)生器是各種測(cè)試和實(shí)驗(yàn)過(guò)程中不可缺少的工具,在通信、測(cè)量、雷達(dá)、控制、教學(xué)等領(lǐng)域應(yīng)用十分廣泛。不論是在生產(chǎn)、科研還是教學(xué)上,信號(hào)發(fā)生器都是電子工程師信號(hào)仿真實(shí)驗(yàn)的最佳工具。而且,信號(hào)發(fā)生器的設(shè)計(jì)方法多,設(shè)計(jì)技術(shù)也越來(lái)越先進(jìn), 隨著我國(guó)經(jīng)濟(jì)和科技的發(fā)展, 對(duì)相應(yīng)的測(cè)試儀器和測(cè)試手段也提出了更高的要求,信號(hào)發(fā)生器己成為測(cè)試儀器中至關(guān)重要的一類,因此開(kāi)發(fā)信號(hào)發(fā)生器具有重大意義。

二、主程序流程圖

對(duì)系統(tǒng)運(yùn)行工作流程進(jìn)行說(shuō)明后,給出系統(tǒng)主程序流程。

設(shè)計(jì)思路:首先將所有配置進(jìn)行初始化,為了消除干擾和提升仿真效率,我們將系統(tǒng)的工作狀態(tài)分為兩種,一種為調(diào)整狀態(tài),另一種為波形輸出狀態(tài),使用一個(gè)開(kāi)關(guān)的通斷來(lái)調(diào)整。

系統(tǒng)主程序流程圖如圖4-1所示。

圖片

三、 Proteus軟件仿真調(diào)試

正弦波

圖片

方波

圖片

三角波

圖片

鋸齒波

圖片

四、 硬件調(diào)試

在實(shí)際電路中,我們可以將頻率調(diào)整的快一點(diǎn),但是要注意抗干擾問(wèn)題,畢竟上面的都是理論值,模擬信號(hào)非常容易受到其他因素的干擾。所有配置,都必須跟程序里面完全一致,如果波形失真,或者頻率不對(duì),還應(yīng)進(jìn)行相對(duì)應(yīng)的補(bǔ)償。

五、 程序清單

#include "stm32f10x.h"

#include "sys.h"

#include "delay.h"

#include "12864.h"

#include "key4_4.h"

#include "timer.h"

#define KEY0 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_10)//讀取按鍵0

void Delay_Ms(u16 time);

/*************** 配置Switch用到的I/O口*******************/

void Init_GPIO_Switch(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);

//關(guān)閉jtag,使能SWD,可以用SWD模式調(diào)試

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);

// 使能PC端口時(shí)鐘

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;

//PC0

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

//IO口速度為50MHz

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

//設(shè)置成輸入

GPIO_Init(GPIOB, &GPIO_InitStructure);

//初始化PC0

}

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

*功能名稱:main

*描述:主程序。

*輸入:無(wú)

*輸出:無(wú)

*返回:無(wú)

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

int main(void)

{

u8 i=0;

RCC_ClocksTypeDef RCC_Clocks; //初始化程序

RCC_Configuration(RCC_PLLMul_4); //8M*4 == 32M

RCC_GetClocksFreq(&RCC_Clocks); //獲取片上時(shí)鐘

Init_12864(); //初始化12864液晶

Key_Init();

Init_GPIO_Switch();

Init_GPIO_DAC0832();

Data0=25;

TIM3_Int_Init(50+Data0,320);

//頻率:32000000/ 320 ==100 000 /100 == 1000 /50==20

LCD_P6x8Str(3,16," Sine Wave ");

LCD_P6x8Str(7,6*2,"Frequency: 15 Hz");

while (1)

{

if(KEY0)

{

if(i!=2)

{

__set_PRIMASK(1);

GPIO_ResetBits(GPIOB, ((uint16_t)0xC000));

}

Key_Test();

i=2;

}

else{

if(i!=5)

{

TIM3_Int_Init(50+Data0,320);

__set_PRIMASK(0); //使能TIMx外設(shè)

GPIO_ResetBits(GPIOB, ((uint16_t)0xC000));

}

i=5;

}

}

}

/*************** 定時(shí)器*******************/

#include "timer.h"

#include "math.h"

#define ADC_CS_WR(a) if (a)

GPIO_SetBits(GPIOB,GPIO_Pin_14);

else

GPIO_ResetBits(GPIOB,GPIO_Pin_14)

#define ADC_CS_WR2(a) if (a)

GPIO_SetBits(GPIOB,GPIO_Pin_15);

else

GPIO_ResetBits(GPIOB,GPIO_Pin_15)

#define PI 3.1415926f //圓周率

u8 mode; //模式:正弦波……

u16 freq; //頻率

u8 time; //計(jì)次參數(shù)

u8 AM; //調(diào)幅

/*************** 配置DAC用到的I/O口*******************/

void Init_GPIO_DAC0832(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE); // 使能PC端口時(shí)鐘

GPIO_InitStructure.GPIO_Pin = ((uint16_t)0x03FF); //選擇對(duì)應(yīng)的引腳

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽輸出

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度為50MHz

GPIO_Init(GPIOC, &GPIO_InitStructure); //初始化PC端口

GPIO_SetBits(GPIOC, ((uint16_t)0x00FF)); // 高

GPIO_ResetBits(GPIOC, ((uint16_t)0x00FF)); // 低

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); // 使能PC端口時(shí)鐘

GPIO_InitStructure.GPIO_Pin = ((uint16_t)0xC000); //選擇對(duì)應(yīng)的引腳

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽輸出

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度為50MHz

GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化PC端口

GPIO_SetBits(GPIOC, ((uint16_t)0xC000)); // 高

GPIO_ResetBits(GPIOC, ((uint16_t)0xC000)); // 低

time=0;

ADC_CS_WR(0);

mode=0; //默認(rèn)輸出正弦波

freq=100; //默認(rèn)頻率

AM=255; //最大幅度

}

void DAC_0832_Data(uint8_t Data)

{

GPIO_ResetBits(GPIOC,~Data);

GPIO_SetBits(GPIOC,Data);

}

void sine_wave(u8 location)//輸出正弦波

{

double x=(double)location/50*PI;//把0-100放縮到0-2派(pai,沒(méi)有那個(gè)符號(hào))

u8 y=(sin(x)*(AM/2)+(AM/2));//算出y,并放縮到0-254(因?yàn)锳DC范圍0-AM,芯片落后)

DAC_0832_Data(y);

}

void squ_wave(u8 location)//方……

{

if(location<50)

DAC_0832_Data(AM);

else

DAC_0832_Data(0);//這個(gè)簡(jiǎn)單

}

void tri_wave(u8 location)//三……

{

//為了簡(jiǎn)化,在單周期輸出V字形

u8 y;

if(location<50)

y=(50-location)*AM/50;

else

y=(location-50)*AM/50;

DAC_0832_Data(y);

//偶函數(shù),當(dāng)然說(shuō)奇函數(shù)也沒(méi)錯(cuò)

}

void saw_wave(u8 location)//鋸……

{

DAC_0832_Data(location*AM/100);

//用(100-location)也以變成反向鋸齒

}

//通用定時(shí)器中斷初始化

//這里時(shí)鐘選擇為APB1的2倍,而APB1為36M

//arr:自動(dòng)重裝值。

//psc:時(shí)鐘預(yù)分頻數(shù)

//這里使用的是定時(shí)器3!

void TIM3_Int_Init(u16 arr,u16 psc)

{

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

NVIC_InitTypeDef NVIC_InitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //時(shí)鐘使能

TIM_TimeBaseStructure.TIM_Period = arr; //設(shè)置在下一個(gè)更新事件裝入活動(dòng)的自動(dòng)重裝載寄存器周期的值 計(jì)數(shù)到5000為500ms

TIM_TimeBaseStructure.TIM_Prescaler =psc; //設(shè)置用來(lái)作為T(mén)IMx時(shí)鐘頻率除數(shù)的預(yù)分頻值 10Khz的計(jì)數(shù)頻率

TIM_TimeBaseStructure.TIM_ClockDivision = 0; //設(shè)置時(shí)鐘分割:TDTS = Tck_tim

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上計(jì)數(shù)模式

TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根據(jù)TIM_TimeBaseInitStruct中指定的參數(shù)初始化TIMx的時(shí)間基數(shù)單位

TIM_ITConfig( //使能或者失能指定的TIM中斷

TIM3, //TIM3

TIM_IT_Update ,

ENABLE //使能

);

// TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);

NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3中斷

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占優(yōu)先級(jí)0級(jí)

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //從優(yōu)先級(jí)3級(jí)

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能

NVIC_Init(&NVIC_InitStructure); //根據(jù)NVIC_InitStruct中指定的參數(shù)初始化外設(shè)NVIC寄存器

TIM_Cmd(TIM3, ENABLE); //使能TIMx外設(shè)

// TIM_Cmd(TIM3, DISABLE);

}

void TIM3_IRQHandler(void) //TIM3中斷

{

switch(mode)

{

case W_SINE:sine_wave((u8)(time*freq/100)%100);break;//計(jì)算出波的位置

case W_SQU:squ_wave((u8)((time*freq/100)%100));break;

case W_TRI:tri_wave((u8)((time*freq/100)%100));break;

case W_SAW:saw_wave((u8)((time*freq/100)%100));break;

}

time++;

if(time>=100)//計(jì)數(shù)100次

time=0;

}

#include "key4_4.h"

#include "delay.h"

#include "sys.h"

#include "12864.h"

#include "timer.h"

//8個(gè)引腳 4個(gè)為行 4個(gè)為列

//行輸出端口定義

#define X1_GPIO_PORT GPIOB

#define X2_GPIO_PORT GPIOB

#define X3_GPIO_PORT GPIOB

#define X4_GPIO_PORT GPIOB

//列輸入端口定義

#define Y1_GPIO_PORT GPIOB

#define Y2_GPIO_PORT GPIOB

#define Y3_GPIO_PORT GPIOB

#define Y4_GPIO_PORT GPIOB

//行輸出引腳定義

#define X1_GPIO_PIN GPIO_Pin_0

#define X2_GPIO_PIN GPIO_Pin_1

#define X3_GPIO_PIN GPIO_Pin_2

#define X4_GPIO_PIN GPIO_Pin_3

//列輸入引腳定義

#define Y1_GPIO_PIN GPIO_Pin_4

#define Y2_GPIO_PIN GPIO_Pin_5

#define Y3_GPIO_PIN GPIO_Pin_6

#define Y4_GPIO_PIN GPIO_Pin_7

//行輸出時(shí)鐘定義

#define X1_RCC RCC_APB2Periph_GPIOB

#define X2_RCC RCC_APB2Periph_GPIOB

#define X3_RCC RCC_APB2Periph_GPIOB

#define X4_RCC RCC_APB2Periph_GPIOB

//列輸入時(shí)鐘定義

#define Y1_RCC RCC_APB2Periph_GPIOB

#define Y2_RCC RCC_APB2Periph_GPIOB

#define Y3_RCC RCC_APB2Periph_GPIOB

#define Y4_RCC RCC_APB2Periph_GPIOB

//移植代碼只需要修改上面的端口和引腳和時(shí)鐘即可,下面的代碼不用修改。

//矩陣鍵盤(pán)所用的8個(gè)引腳可連續(xù)可不連續(xù),看實(shí)際需要和個(gè)人愛(ài)好自己定義。

unsigned char Y1,Y2,Y3,Y4;

void Key_Init(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB2PeriphClockCmd(X1_RCC|X2_RCC|X3_RCC|X4_RCC|Y1_RCC|Y2_RCC|Y3_RCC|Y4_RCC|RCC_APB2Periph_AFIO, ENABLE);

GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);

/*******************4行輸出 *****************************/

GPIO_InitStructure.GPIO_Pin = X1_GPIO_PIN ;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;

GPIO_Init(X1_GPIO_PORT, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = X2_GPIO_PIN ;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;

GPIO_Init(X2_GPIO_PORT, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = X3_GPIO_PIN ;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;

GPIO_Init(X3_GPIO_PORT, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;

GPIO_InitStructure.GPIO_Pin = X4_GPIO_PIN ;

GPIO_Init(X4_GPIO_PORT, &GPIO_InitStructure);

/******************* 4列輸入 *******************/

GPIO_InitStructure.GPIO_Pin = Y1_GPIO_PIN ;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;

GPIO_Init(Y1_GPIO_PORT, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = Y2_GPIO_PIN ;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;

GPIO_Init(Y2_GPIO_PORT, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = Y3_GPIO_PIN ;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;

GPIO_Init(Y3_GPIO_PORT, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;

GPIO_InitStructure.GPIO_Pin = Y4_GPIO_PIN;

GPIO_Init(Y4_GPIO_PORT, &GPIO_InitStructure);

}

int Key_Scan(void)

{

uchar KeyVal;

GPIO_SetBits(X1_GPIO_PORT,X1_GPIO_PIN); //先讓X1輸出高

GPIO_SetBits(X2_GPIO_PORT,X2_GPIO_PIN); //先讓X2輸出高

GPIO_SetBits(X3_GPIO_PORT,X3_GPIO_PIN); //先讓X3輸出高

GPIO_SetBits(X4_GPIO_PORT,X4_GPIO_PIN); //先讓X4輸出高

if((GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN)|GPIO_ReadInputDataBit(Y2_GPIO_PORT,Y2_GPIO_PIN)|GPIO_ReadInputDataBit(Y3_GPIO_PORT,Y3_GPIO_PIN)|GPIO_ReadInputDataBit(Y4_GPIO_PORT,Y4_GPIO_PIN))==0x0000)

return -1; //如果X1到X4全為零則沒(méi)有按鍵按下

else

{

Delay_Ms(5); //延時(shí)5ms去抖動(dòng)

if((GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN)|GPIO_ReadInputDataBit(Y2_GPIO_PORT,Y2_GPIO_PIN)|GPIO_ReadInputDataBit(Y3_GPIO_PORT,Y3_GPIO_PIN)|GPIO_ReadInputDataBit(Y4_GPIO_PORT,Y4_GPIO_PIN))==0x0000)

return -1;

}

GPIO_ResetBits(X1_GPIO_PORT,X1_GPIO_PIN);

GPIO_ResetBits(X2_GPIO_PORT,X2_GPIO_PIN);

GPIO_ResetBits(X3_GPIO_PORT,X3_GPIO_PIN);

GPIO_SetBits(X4_GPIO_PORT,X4_GPIO_PIN);

Y1=GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN);Y2=GPIO_ReadInputDataBit(Y2_GPIO_PORT,Y2_GPIO_PIN);

Y3=GPIO_ReadInputDataBit(Y3_GPIO_PORT,Y3_GPIO_PIN);Y4=GPIO_ReadInputDataBit(Y4_GPIO_PORT,Y4_GPIO_PIN);

if(Y1==1&&Y2==0&&Y3==0&&Y4==0)

KeyVal='*';

if(Y1==0&&Y2==1&&Y3==0&&Y4==0)

KeyVal=0;

if(Y1==0&&Y2==0&&Y3==0&&Y4==1)

KeyVal='D';

if(Y1==0&&Y2==0&&Y3==1&&Y4==0)

KeyVal='#';

while(((GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN))|(GPIO_ReadInputDataBit(Y2_GPIO_PORT,Y2_GPIO_PIN))|(GPIO_ReadInputDataBit(Y3_GPIO_PORT,Y3_GPIO_PIN))|(GPIO_ReadInputDataBit(Y4_GPIO_PORT,Y4_GPIO_PIN))) > 0);

//等待按鍵釋放

GPIO_SetBits(X1_GPIO_PORT,X1_GPIO_PIN);

GPIO_ResetBits(X2_GPIO_PORT,X2_GPIO_PIN);

GPIO_ResetBits(X3_GPIO_PORT,X3_GPIO_PIN);

GPIO_ResetBits(X4_GPIO_PORT,X4_GPIO_PIN);

Y1=GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN);Y2=GPIO_ReadInputDataBit(Y2_GPIO_PORT,Y2_GPIO_PIN);

Y3=GPIO_ReadInputDataBit(Y3_GPIO_PORT,Y3_GPIO_PIN);Y4=GPIO_ReadInputDataBit(Y4_GPIO_PORT,Y4_GPIO_PIN);

if(Y1==1&&Y2==0&&Y3==0&&Y4==0)

KeyVal=1;

if(Y1==0&&Y2==1&&Y3==0&&Y4==0)

KeyVal=2;

if(Y1==0&&Y2==0&&Y3==1&&Y4==0)

KeyVal=3;

if(Y1==0&&Y2==0&&Y3==0&&Y4==1)

KeyVal='A';

while(((GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN))|(GPIO_ReadInputDataBit(Y2_GPIO_PORT,Y2_GPIO_PIN))|(GPIO_ReadInputDataBit(Y3_GPIO_PORT,Y3_GPIO_PIN))|(GPIO_ReadInputDataBit(Y4_GPIO_PORT,Y4_GPIO_PIN))) > 0);

GPIO_ResetBits(X1_GPIO_PORT,X1_GPIO_PIN);

GPIO_SetBits(X2_GPIO_PORT,X2_GPIO_PIN);

GPIO_ResetBits(X3_GPIO_PORT,X3_GPIO_PIN);

GPIO_ResetBits(X4_GPIO_PORT,X4_GPIO_PIN);

Y1=GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN);Y2=GPIO_ReadInputDataBit(Y2_GPIO_PORT,Y2_GPIO_PIN);

Y3=GPIO_ReadInputDataBit(Y3_GPIO_PORT,Y3_GPIO_PIN);Y4=GPIO_ReadInputDataBit(Y4_GPIO_PORT,Y4_GPIO_PIN);

if(Y1==1&&Y2==0&&Y3==0&&Y4==0)

KeyVal=4;

if(Y1==0&&Y2==1&&Y3==0&&Y4==0)

KeyVal=5;

if(Y1==0&&Y2==0&&Y3==1&&Y4==0)

KeyVal=6;

if(Y1==0&&Y2==0&&Y3==0&&Y4==1)

KeyVal='B';

while(((GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN))|(GPIO_ReadInputDataBit(Y2_GPIO_PORT,Y2_GPIO_PIN))|(GPIO_ReadInputDataBit(Y3_GPIO_PORT,Y3_GPIO_PIN))|(GPIO_ReadInputDataBit(Y4_GPIO_PORT,Y4_GPIO_PIN))) > 0);

GPIO_ResetBits(X1_GPIO_PORT,X1_GPIO_PIN);

GPIO_ResetBits(X2_GPIO_PORT,X2_GPIO_PIN);

GPIO_SetBits(X3_GPIO_PORT,X3_GPIO_PIN);

GPIO_ResetBits(X4_GPIO_PORT,X4_GPIO_PIN);

Y1=GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN);Y2=GPIO_ReadInputDataBit(Y2_GPIO_PORT,Y2_GPIO_PIN);

Y3=GPIO_ReadInputDataBit(Y3_GPIO_PORT,Y3_GPIO_PIN);Y4=GPIO_ReadInputDataBit(Y4_GPIO_PORT,Y4_GPIO_PIN);

if(Y1==1&&Y2==0&&Y3==0&&Y4==0)

KeyVal=7;

if(Y1==0&&Y2==1&&Y3==0&&Y4==0)

KeyVal=8;

if(Y1==0&&Y2==0&&Y3==1&&Y4==0)

KeyVal=9;

if(Y1==0&&Y2==0&&Y3==0&&Y4==1)

KeyVal='C';

while(((GPIO_ReadInputDataBit(Y1_GPIO_PORT,Y1_GPIO_PIN))|(GPIO_ReadInputDataBit(Y2_GPIO_PORT,Y2_GPIO_PIN))|(GPIO_ReadInputDataBit(Y3_GPIO_PORT,Y3_GPIO_PIN))|(GPIO_ReadInputDataBit(Y4_GPIO_PORT,Y4_GPIO_PIN))) > 0);

return KeyVal;

}

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

按鍵表盤(pán)為: 1 2 3 A

4 5 6 B

7 8 9 C

  • 0 # D

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

u8 ee,Data0=0;

void Key_Test(void)

{

int num;

char Freq[3]={'?'};

num = Key_Scan();

if(ee!=num)

switch(num)

{

case 0: LCD_P6x8Str(1,1,"0"); break;

case 1: LCD_P6x8Str(1,1,"1"); break;

case 2: LCD_P6x8Str(1,1,"2"); break;

case 3: LCD_P6x8Str(1,1,"3"); break;

case 4: LCD_P6x8Str(1,1,"4"); break;

case 5: LCD_P6x8Str(1,1,"5"); break;

case 6: LCD_P6x8Str(1,1,"6"); break;

case 7: LCD_P6x8Str(1,1,"7"); break;

case 8: LCD_P6x8Str(1,1,"8"); break;

case 9: LCD_P6x8Str(1,1,"9"); break;//

case'A':LCD_P6x8Str(1,1,"A");

mode=0;LCD_P6x8Str(3,16," Sine Wave "); break;

case'B':LCD_P6x8Str(1,1,"B");

mode=1;LCD_P6x8Str(3,16," Square wave "); break;

case'C':LCD_P6x8Str(1,1,"C"); mode=2;LCD_P6x8Str(3,16,"Ttiangular wave"); break;

case 'D': LCD_P6x8Str(1,1,"D");

mode=3;LCD_P6x8Str(3,16," Sawtooth Wave ");

break;

case '#': LCD_P6x8Str(1,1,"#");

if(Data0>=5)Data0-=5;

Freq[0]=(20-Data0/5)/10+'0';

Freq[1]=(20-Data0/5)%10+'0';

LCD_P6x8Str(7,6*13,Freq);

break;

case ' ': LCD_P6x8Str(1,1," ");

if(Data0<50)Data0+=5; Freq[0]=(20-Data0/5)/10+'0';

Freq[1]=(20-Data0/5)%10+'0';

LCD_P6x8Str(7,6*13,Freq);

break;

}

ee=num;

}

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

12864

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

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

//寫(xiě)數(shù)據(jù)地址

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

void write_12864com(uint8_t com)

{

uint8_t temp = 0x01;

uint8_t k[8] = {0};

uint8_t i;

Check_status();

for(i=0; i<8; i++)

{

if(com & temp)

k[i] = 1;

else

k[i] = 0;

temp=temp << 1;

}

temp = 0x01;

RS=0;

RW=0;

D0=k[0];

D1=k[1];

D2=k[2];

D3=k[3];

D4=k[4];

D5=k[5];

D6=k[6];

D7=k[7];

En=1;

Delay_Ms(1);

En=0;

Delay_Ms(1);

}

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

//寫(xiě)數(shù)據(jù)

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

void write_12864data(uint8_t dat)

{

uint8_t temp = 0x01;

uint8_t k[8] = {0};

uint8_t i;

Check_status();//延時(shí)檢查很重要,在連續(xù)刷新的時(shí)候

for(i=0; i<8; i++)

{

if(dat & temp)

k[i] = 1;

else

k[i] = 0;

temp=temp << 1;

}

temp = 0x01;

RS=1;

RW=0;

D0=k[0];

D1=k[1];

D2=k[2];

D3=k[3];

D4=k[4];

D5=k[5];

D6=k[6];

D7=k[7];

En=1;//在使能信號(hào)的下降沿寫(xiě)入了數(shù)據(jù)

Delay_Ms(1);

En=0;

Delay_Ms(1);

}

uint8_t read_12864data()

{

//這個(gè)函數(shù)的代碼測(cè)試未通過(guò)

uint8_t temp = 0;

uint8_t k[8] = {0};

uint8_t i;

Check_status();

RS=1;

RW=1;

En=1;//使能端高電平讀取數(shù)據(jù)

Delay_Ms(1);

LCD12864_DataRead_PortInit();//端口方向改為輸入

k[0]=DI0;

k[1]=DI1;

k[2]=DI2;

k[3]=DI3;

k[4]=DI4;

k[5]=DI5;

k[6]=DI6;

k[7]=DI7;

LCD12864_DataWrite_PortInit();//端口方向改為輸出

for (i=0; i<8; i++)

{

temp |= ((k[i]&0x01)<

}

return temp;

}

void LCD_Set_Pos(uint8_t page,uint8_t x)//LCD當(dāng)前光標(biāo)設(shè)置,先選頁(yè),后選橫向起始坐標(biāo)

{

uint8_t Column=0;

(x>127)?(x=127):(x=x);

(x<1)?(x=0):(x=x);

if (page>8)

{

page=8;

}

else if (page<1)

{

page=1;

}

page=page-1;

if (x<=63)

{ LCDSelectScreen(LeftScreen);

LCDSetPage(page);

Column=x;

LCDSetColumn(Column);

}

else if (x>63)

{ LCDSelectScreen(RightScreen);

LCDSetPage(page);

Column = x-64;

LCDSetColumn(Column);

// if (Column == 0)

// { //如果第一次進(jìn)入右半屏,需要空寫(xiě)一次,在設(shè)置一次,方可

// write_12864data(0x00);

// }

LCDSelectScreen(RightScreen);//上面的判斷不對(duì),應(yīng)該是寫(xiě)兩次命令就會(huì)解決右半屏首字下沉那個(gè)問(wèn)題

LCDSetPage(page);

Column = x-64;

LCDSetColumn(Column);

}

}

void LCD_P6x8Str(uint8_t x, uint8_t y, char ch[])

{

uint8_t c = 0, i = 0, j = 0;

while (ch[j] != '?')

{

c = ch[j]-32;

for (i = 0; i < 6; i++)

{ LCD_Set_Pos(x, y);//因?yàn)檫@個(gè)AMPIRE 分為左右半屏,所以光標(biāo)設(shè)置必須寫(xiě)在這里,確保每個(gè)字符是完整的

write_12864data(F6x8[c][i]);

y = y+1;

}

j++;

}

}

void LCD_DispACat(unsigned char x, unsigned char y)

{

unsigned char i = 0, j = 0;

if (x > 4)

{

x = 4;

y++;

}

x=x-1;

for (j = 0; j < 4; j++)

{

LCD_Set_Pos(x, y);

x++;

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

write_12864data(LCD_cat[i + j * 32]);

}

}

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

//12864初始化

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

void Init_12864()

{

//端口初始化

RCC->APB2ENR|=1<<2; //使能PORTA時(shí)鐘

GPIOA->CRH&=0X00000000;

GPIOA->CRH|=0X44333333;//PA8~13推挽輸出,PA14,15浮空輸入,因?yàn)檫@個(gè)型號(hào)的LCD要檢測(cè)內(nèi)部是否忙

GPIOA->ODR|=0X00FFFFFF;//PA8~13輸出高

LCD12864_DataWrite_PortInit();

Reset=0;

Delay_Ms(1);

Reset=1;

Check_status();

LCDSelectScreen(AllScreen);//屏幕選擇全屏

LCDSetOnOff(Off);

LCDSelectScreen(AllScreen);//屏幕選擇全屏

LCDSetOnOff(On);

LCDSelectScreen(AllScreen);//屏幕選擇全屏

LCDClearScreen(AllScreen);//清屏

LCDSetLine(0);

}

void LCD12864_DataWrite_PortInit()

{

RCC->APB2ENR|=1<<2;

GPIOA->CRL&=0X00000000; //PORTA低八位為數(shù)據(jù)位,推挽輸出,寫(xiě)數(shù)據(jù)用

GPIOA->CRL|=0X33333333;

GPIOA->ODR|=0XFFFFFFFF;

}

void LCD12864_DataRead_PortInit()

{

RCC->APB2ENR|=1<<2;

GPIOA->CRL&=0X00000000; //PORTA低八位為數(shù)據(jù)位,浮空輸入,讀數(shù)據(jù)用

GPIOA->CRL|=0X44444444;

//GPIOA->ODR|=0XFFFFFFFF;

}

void LCDSelectScreen(ScreenTypedef screen)

{

switch(screen)

{

case AllScreen:

CS1=0;

CS2=0;

break;

case LeftScreen:

CS1=0;

CS2=1;

break;

case RightScreen:

CS1=1;

CS2=0;

break;

default :

break;

}

}

void LCDSetOnOff(LCDSetOnOffTypedef Status)

{

switch (Status)

{

case On:

write_12864com(0x3e+1);

break;

case Off:

write_12864com(0x3e);

break;

default:

break;

}

}

void LCDClearScreen(ScreenTypedef screen)

{

uint8_t i,j;

LCDSelectScreen(screen);

for (i=0; i<=7; i++)

{

LCDSetPage(i);

LCDSetColumn(0);

for(j=0; j<=63; j++)

{

write_12864data(0x00);//寫(xiě)完后地址自動(dòng)加一

}

}

}

void LCDSetPage(uint8_t Page)

{

Page=0xb8|Page;

write_12864com(Page);

}

void LCDSetLine(uint8_t Line)

{

Line=0xc0|Line;

write_12864com(Line);

}

void LCDSetColumn(uint8_t Colnum)

{

Colnum=Colnum&0x3f;

Colnum=Colnum|0x40;

write_12864com(Colnum);

}

void Check_status()

{

D0=0;

D1=0;

D2=0;

D3=0;

D4=0;

D5=0;

D6=0;

D7=0;

RS=0;

RW=1;

//En=1;

// while(CheckPin == 0);//不啟用忙檢測(cè)

Delay_Ms(2);

//En=0;

}

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 正弦波
    +關(guān)注

    關(guān)注

    11

    文章

    619

    瀏覽量

    54932
  • STM32
    +關(guān)注

    關(guān)注

    2257

    文章

    10828

    瀏覽量

    352433
  • 信號(hào)發(fā)生器

    關(guān)注

    28

    文章

    1399

    瀏覽量

    108375
  • 波形發(fā)生器
    +關(guān)注

    關(guān)注

    3

    文章

    288

    瀏覽量

    31305
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    基于stm32波形發(fā)生器設(shè)計(jì)

    #include “dac.h”//DAC 通道 1 輸出初始化void Dac1_Init(void){GPIO_InitTypeDef GPIO_InitStructure;DAC_InitTypeDef DAC_InitType;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE ); //①使能 PA 時(shí)鐘RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE ); //②使能DAC時(shí)鐘G
    發(fā)表于 08-16 08:39

    如何去實(shí)現(xiàn)一種基于stm32波形發(fā)生器

    如何去實(shí)現(xiàn)一種基于stm32波形發(fā)生器呢?其代碼程序該怎樣去實(shí)現(xiàn)呢?
    發(fā)表于 11-17 06:19

    怎么實(shí)現(xiàn)基于STM32波形發(fā)生器的設(shè)計(jì)?

    怎么實(shí)現(xiàn)基于STM32波形發(fā)生器的設(shè)計(jì)?
    發(fā)表于 11-26 06:16

    程序波形發(fā)生器電路

    程序波形發(fā)生器電路 程序波形發(fā)生器
    發(fā)表于 02-09 16:07 ?953次閱讀
    程序<b class='flag-5'>波形</b><b class='flag-5'>發(fā)生器</b>電路

    SPWM波形發(fā)生器設(shè)計(jì)與應(yīng)用

    SPWM波形發(fā)生器設(shè)計(jì)與應(yīng)用
    發(fā)表于 07-24 16:11 ?5876次閱讀
    SPWM<b class='flag-5'>波形</b><b class='flag-5'>發(fā)生器</b>設(shè)計(jì)與應(yīng)用

    波形發(fā)生器設(shè)計(jì)簡(jiǎn)述

    在工作中,我們常常會(huì)用到波形發(fā)生器,它是使用頻度很高的電子儀器?,F(xiàn)在的波形發(fā)生器都采用單片機(jī)來(lái)構(gòu)成。單片機(jī)波形
    發(fā)表于 03-28 15:43 ?0次下載

    波形發(fā)生器

    波形發(fā)生器,可以生成4中波形。正玄波,矩形波,三角波等。
    發(fā)表于 05-13 10:17 ?30次下載

    波形發(fā)生器的設(shè)計(jì)

    波形發(fā)生器的設(shè)計(jì)
    發(fā)表于 12-17 21:49 ?29次下載

    簡(jiǎn)易波形發(fā)生器

    簡(jiǎn)易波形發(fā)生器
    發(fā)表于 01-05 14:34 ?29次下載

    波形發(fā)生器

    多種波形發(fā)生器課程設(shè)計(jì)。
    發(fā)表于 02-08 02:37 ?179次下載

    波形發(fā)生器應(yīng)用的測(cè)量

    波形發(fā)生器應(yīng)用的測(cè)量
    發(fā)表于 03-28 10:24 ?1次下載

    關(guān)于波形發(fā)生器的設(shè)計(jì)

    波形發(fā)生器
    發(fā)表于 07-03 15:31 ?120次下載

    iboard教程之基于STM32波形發(fā)生器的軟件分析

    發(fā)表于 10-29 09:22 ?0次下載
    iboard教程之基于<b class='flag-5'>STM32</b>的<b class='flag-5'>波形</b><b class='flag-5'>發(fā)生器</b>的軟件分析

    關(guān)于波形發(fā)生器,你知道多少?

    信號(hào)發(fā)生器系列波形發(fā)生器你知道多少?虹科信號(hào)發(fā)生器系列波形發(fā)生器
    的頭像 發(fā)表于 08-05 08:07 ?2706次閱讀
    關(guān)于<b class='flag-5'>波形</b><b class='flag-5'>發(fā)生器</b>,你知道多少?

    什么是任意波形發(fā)生器

    在電子測(cè)量、通信、科研以及音樂(lè)創(chuàng)作等多個(gè)領(lǐng)域中,波形發(fā)生器作為一種能夠產(chǎn)生特定波形信號(hào)的電子設(shè)備,發(fā)揮著不可或缺的作用。而任意波形發(fā)生器(A
    的頭像 發(fā)表于 05-30 15:53 ?599次閱讀