一、項目介紹
信號發(fā)生器在生產(chǎn)實踐和科技領(lǐng)域中有著廣泛的應(yīng)用,各種波形曲線均可以用三角函數(shù)方程式來表示。能夠產(chǎn)生多種波形,如三角波、鋸齒波、矩形波(含方波)、正弦波的電路被稱為函數(shù)信號發(fā)生器。函數(shù)信號發(fā)生器在電路實驗和設(shè)備檢測中具有十分廣泛的用途,例如在通信、廣播、電視系統(tǒng)中,都需要射頻(高頻)發(fā)射。這里的射頻波就是載波,把音頻(低頻)、視頻信號或脈沖信號運載出去,就需要能夠產(chǎn)生高頻的振蕩器。在工業(yè)、農(nóng)業(yè)、生物醫(yī)學(xué)等領(lǐng)域內(nèi),如高頻感應(yīng)加熱、熔煉、淬火、超聲診斷、核磁共振成像等,都需要功率或大或小、頻率或高或低的振蕩器。函數(shù)信號發(fā)生器是各種測試和實驗過程中不可缺少的工具,在通信、測量、雷達(dá)、控制、教學(xué)等領(lǐng)域應(yīng)用十分廣泛。不論是在生產(chǎn)、科研還是教學(xué)上,信號發(fā)生器都是電子工程師信號仿真實驗的最佳工具。而且,信號發(fā)生器的設(shè)計方法多,設(shè)計技術(shù)也越來越先進(jìn), 隨著我國經(jīng)濟和科技的發(fā)展, 對相應(yīng)的測試儀器和測試手段也提出了更高的要求,信號發(fā)生器己成為測試儀器中至關(guān)重要的一類,因此開發(fā)信號發(fā)生器具有重大意義。
二、主程序流程圖
對系統(tǒng)運行工作流程進(jìn)行說明后,給出系統(tǒng)主程序流程。
設(shè)計思路:首先將所有配置進(jìn)行初始化,為了消除干擾和提升仿真效率,我們將系統(tǒng)的工作狀態(tài)分為兩種,一種為調(diào)整狀態(tài),另一種為波形輸出狀態(tài),使用一個開關(guān)的通斷來調(diào)整。
系統(tǒng)主程序流程圖如圖4-1所示。
三、 Proteus軟件仿真調(diào)試
正弦波
方波
三角波
鋸齒波
四、 硬件調(diào)試
在實際電路中,我們可以將頻率調(diào)整的快一點,但是要注意抗干擾問題,畢竟上面的都是理論值,模擬信號非常容易受到其他因素的干擾。所有配置,都必須跟程序里面完全一致,如果波形失真,或者頻率不對,還應(yīng)進(jìn)行相對應(yīng)的補償。
五、 程序清單
#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);
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
*描述:主程序。
*輸入:無
*輸出:無
*返回:無
****************************************************************/
int main(void)
{
u8 i=0;
RCC_ClocksTypeDef RCC_Clocks; //初始化程序
RCC_Configuration(RCC_PLLMul_4); //8M*4 == 32M
RCC_GetClocksFreq(&RCC_Clocks); //獲取片上時鐘
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;
}
}
}
/*************** 定時器*******************/
#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; //計次參數(shù)
u8 AM; //調(diào)幅
/*************** 配置DAC用到的I/O口*******************/
void Init_GPIO_DAC0832(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE); // 使能PC端口時鐘
GPIO_InitStructure.GPIO_Pin = ((uint16_t)0x03FF); //選擇對應(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端口時鐘
GPIO_InitStructure.GPIO_Pin = ((uint16_t)0xC000); //選擇對應(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,沒有那個符號)
u8 y=(sin(x)*(AM/2)+(AM/2));//算出y,并放縮到0-254(因為ADC范圍0-AM,芯片落后)
DAC_0832_Data(y);
}
void squ_wave(u8 location)//方……
{
if(location<50)
DAC_0832_Data(AM);
else
DAC_0832_Data(0);//這個簡單
}
void tri_wave(u8 location)//三……
{
//為了簡化,在單周期輸出V字形
u8 y;
if(location<50)
y=(50-location)*AM/50;
else
y=(location-50)*AM/50;
DAC_0832_Data(y);
//偶函數(shù),當(dāng)然說奇函數(shù)也沒錯
}
void saw_wave(u8 location)//鋸……
{
DAC_0832_Data(location*AM/100);
//用(100-location)也以變成反向鋸齒
}
//通用定時器中斷初始化
//這里時鐘選擇為APB1的2倍,而APB1為36M
//arr:自動重裝值。
//psc:時鐘預(yù)分頻數(shù)
//這里使用的是定時器3!
void TIM3_Int_Init(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //時鐘使能
TIM_TimeBaseStructure.TIM_Period = arr; //設(shè)置在下一個更新事件裝入活動的自動重裝載寄存器周期的值 計數(shù)到5000為500ms
TIM_TimeBaseStructure.TIM_Prescaler =psc; //設(shè)置用來作為TIMx時鐘頻率除數(shù)的預(yù)分頻值 10Khz的計數(shù)頻率
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //設(shè)置時鐘分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上計數(shù)模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根據(jù)TIM_TimeBaseInitStruct中指定的參數(shù)初始化TIMx的時間基數(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)先級0級
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //從優(yōu)先級3級
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;//計算出波的位置
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)//計數(shù)100次
time=0;
}
#include "key4_4.h"
#include "delay.h"
#include "sys.h"
#include "12864.h"
#include "timer.h"
//8個引腳 4個為行 4個為列
//行輸出端口定義
#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
//行輸出時鐘定義
#define X1_RCC RCC_APB2Periph_GPIOB
#define X2_RCC RCC_APB2Periph_GPIOB
#define X3_RCC RCC_APB2Periph_GPIOB
#define X4_RCC RCC_APB2Periph_GPIOB
//列輸入時鐘定義
#define Y1_RCC RCC_APB2Periph_GPIOB
#define Y2_RCC RCC_APB2Periph_GPIOB
#define Y3_RCC RCC_APB2Periph_GPIOB
#define Y4_RCC RCC_APB2Periph_GPIOB
//移植代碼只需要修改上面的端口和引腳和時鐘即可,下面的代碼不用修改。
//矩陣鍵盤所用的8個引腳可連續(xù)可不連續(xù),看實際需要和個人愛好自己定義。
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全為零則沒有按鍵按下
else
{
Delay_Ms(5); //延時5ms去抖動
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;
}
/************************************
按鍵表盤為: 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
//*************************************
//*************************************
//寫數(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);
}
//*************************************
//寫數(shù)據(jù)
//*************************************
void write_12864data(uint8_t dat)
{
uint8_t temp = 0x01;
uint8_t k[8] = {0};
uint8_t i;
Check_status();//延時檢查很重要,在連續(xù)刷新的時候
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;//在使能信號的下降沿寫入了數(shù)據(jù)
Delay_Ms(1);
En=0;
Delay_Ms(1);
}
uint8_t read_12864data()
{
//這個函數(shù)的代碼測試未通過
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è)置,先選頁,后選橫向起始坐標(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)入右半屏,需要空寫一次,在設(shè)置一次,方可
// write_12864data(0x00);
// }
LCDSelectScreen(RightScreen);//上面的判斷不對,應(yīng)該是寫兩次命令就會解決右半屏首字下沉那個問題
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);//因為這個AMPIRE 分為左右半屏,所以光標(biāo)設(shè)置必須寫在這里,確保每個字符是完整的
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時鐘
GPIOA->CRH&=0X00000000;
GPIOA->CRH|=0X44333333;//PA8~13推挽輸出,PA14,15浮空輸入,因為這個型號的LCD要檢測內(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ù)位,推挽輸出,寫數(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);//寫完后地址自動加一
}
}
}
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);//不啟用忙檢測
Delay_Ms(2);
//En=0;
}
-
正弦波
+關(guān)注
關(guān)注
11文章
638瀏覽量
55261 -
STM32
+關(guān)注
關(guān)注
2266文章
10871瀏覽量
354786 -
信號發(fā)生器
+關(guān)注
關(guān)注
28文章
1452瀏覽量
108652 -
波形發(fā)生器
+關(guān)注
關(guān)注
3文章
288瀏覽量
31353
發(fā)布評論請先 登錄
相關(guān)推薦
評論