STM32F103 RCT6 LCD显示正弦波并且设置可以调节振幅的触摸按键代码
时间: 2023-12-03 08:47:49 浏览: 289
以下是基于STM32F103RCT6和Keil MDK-ARM开发环境的LCD显示正弦波并且设置可以调节振幅的触摸按键代码:
```c
#include "stm32f10x.h"
#include "lcd.h" //LCD驱动库
#include "math.h" //数学库
#define PI 3.14159 //圆周率
void delay_ms(uint16_t n);
int main(void)
{
float amplitude = 20; //振幅
float frequency = 1; //频率
float phase = 0; //相位
float voltage = 0;
uint16_t i = 0;
uint16_t j = 0;
uint16_t k = 0;
uint16_t x = 0;
uint16_t y = 0;
uint16_t z = 0;
uint16_t key_value = 0;
uint8_t flag = 0; //标志位
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE); //使能GPIOA、GPIOB、GPIOC时钟
LCD_Init(); //初始化LCD
LCD_Clear(WHITE); //清屏为白色
//配置PA0、PA1、PA2、PA3、PA4、PA5、PA6、PA7为输入模式,设置为下拉输入模式,用于触摸屏按键扫描
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//配置PB0、PB1、PB2、PB10、PB11、PB12、PB13、PB14、PB15为输出模式,用于触摸屏按键扫描
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
//配置PC13为输入模式,用于外部中断触发
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOC, &GPIO_InitStructure);
//配置外部中断
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //使能AFIO时钟
GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource13); //选择外部中断线路
EXTI_InitStructure.EXTI_Line = EXTI_Line13; //选择外部中断线路
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //设置为中断模式
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling; //上下降沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE; //使能外部中断
EXTI_Init(&EXTI_InitStructure); //配置外部中断
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn; //选择外部中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00; //抢占优先级0,最高优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01; //子优先级1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
NVIC_Init(&NVIC_InitStructure); //配置外部中断通道
while(1)
{
//扫描触摸屏按键
GPIO_SetBits(GPIOB, GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2); //PB0、PB1、PB2设置为高电平
GPIO_ResetBits(GPIOB, GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12); //PB10、PB11、PB12设置为低电平
delay_ms(10); //延时10ms,等待电平稳定
key_value = GPIO_ReadInputData(GPIOA) & 0xFF; //读取PA0~7的输入状态
if(key_value != 0xFF) //检测到按键按下
{
if(key_value == 0xFE) //PA0按键按下
{
flag = 1; //标志位设置为1
}
else if(key_value == 0xFD) //PA1按键按下
{
flag = 0; //标志位设置为0
}
else if(key_value == 0xFB) //PA2按键按下
{
amplitude += 5; //振幅增加5
}
else if(key_value == 0xF7) //PA3按键按下
{
amplitude -= 5; //振幅减少5
}
else if(key_value == 0xEF) //PA4按键按下
{
frequency += 0.1; //频率增加0.1
}
else if(key_value == 0xDF) //PA5按键按下
{
frequency -= 0.1; //频率减少0.1
}
else if(key_value == 0xBF) //PA6按键按下
{
phase += 0.1; //相位增加0.1
}
else if(key_value == 0x7F) //PA7按键按下
{
phase -= 0.1; //相位减少0.1
}
}
//显示正弦波
for(i = 0; i < 320; i++)
{
voltage = amplitude * sin(2 * PI * frequency * i / 320 + phase); //计算正弦波电压值
j = (uint16_t)voltage; //转换为整型
if(j > 240) //防止数组越界
{
j = 240;
}
for(k = 0; k < j; k++) //画正弦波
{
x = i;
y = 240 - k;
LCD_SetPoint(x, y, BLACK);
}
for(z = j; z < 240; z++) //清空非正弦波部分
{
x = i;
y = 240 - z;
LCD_SetPoint(x, y, WHITE);
}
}
//显示振幅、频率、相位、标志位状态
LCD_ShowString(0, 0, "Amplitude:");
LCD_ShowNum(80, 0, amplitude, 2, 16);
LCD_ShowString(0, 16, "Frequency:");
LCD_ShowNum(80, 16, frequency, 1, 16);
LCD_ShowString(0, 32, "Phase:");
LCD_ShowNum(80, 32, phase, 1, 16);
LCD_ShowString(0, 48, "Flag:");
LCD_ShowNum(80, 48, flag, 0, 16);
}
}
//延时函数,n为延时时间,单位为毫秒
void delay_ms(uint16_t n)
{
uint16_t i = 0;
for(; n > 0; n--)
{
for(i = 0; i < 8000; i++);
}
}
//外部中断处理函数
void EXTI15_10_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line13) != RESET) //检测到外部中断
{
GPIO_SetBits(GPIOB, GPIO_Pin_13); //PB13设置为高电平
delay_ms(100); //延时100ms,等待电平稳定
if(GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_13) == Bit_RESET) //检测到按键按下
{
while(GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_13) == Bit_RESET); //等待按键释放
if(flag == 1) //标志位为1时,PB14设置为高电平
{
GPIO_SetBits(GPIOB, GPIO_Pin_14);
}
else //标志位为0时,PB15设置为高电平
{
GPIO_SetBits(GPIOB, GPIO_Pin_15);
}
delay_ms(50); //延时50ms,等待电平稳定
GPIO_ResetBits(GPIOB, GPIO_Pin_14 | GPIO_Pin_15); //PB14、PB15设置为低电平
}
EXTI_ClearITPendingBit(EXTI_Line13); //清除中断标志位
}
}
```
说明:
1. 本代码使用了LCD驱动库,在开发前需要先下载并导入到Keil MDK-ARM开发环境中。
2. 本代码使用了数学库,需要在项目设置中勾选使用math库。
3. 本代码使用了外部中断,需要在项目设置中配置外部中断优先级和中断向量表。
4. 本代码使用了触摸屏按键扫描,需要连接触摸屏按键模块,其中PA0~7为输入端口,PB0~2和PB10~15为输出端口。
5. 本代码通过触摸屏按键来调节正弦波的振幅、频率、相位和标志位状态。
6. 本代码通过外部中断来触发PB14或PB15的输出,实现与外设的交互。
阅读全文