创建显示线程

This commit is contained in:
zhan-min 2020-10-25 23:29:08 +08:00
parent dd87c87b99
commit 55e6ffaf7a
9 changed files with 2561 additions and 2843 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -655,7 +655,7 @@
<GroupNumber>4</GroupNumber> <GroupNumber>4</GroupNumber>
<FileNumber>36</FileNumber> <FileNumber>36</FileNumber>
<FileType>1</FileType> <FileType>1</FileType>
<tvExp>0</tvExp> <tvExp>1</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2> <bDave2>0</bDave2>
<PathWithFileName>..\User\OSC\OSC.c</PathWithFileName> <PathWithFileName>..\User\OSC\OSC.c</PathWithFileName>

View File

@ -1,213 +1,100 @@
#include "rtthread.h" #include "rtthread.h"
#include "OSC.h" #include "OSC.h"
#include "stm32f10x.h" #include "stm32f10x.h"
#include "bsp_ili9341_lcd.h" #include "bsp_ili9341_lcd.h"
#include "bsp_usart.h" #include "bsp_usart.h"
#include "bsp_adc.h" #include "bsp_adc.h"
#include "bsp_led.h" #include "bsp_led.h"
#include "bsp_TiMbase.h" #include "bsp_TiMbase.h"
#include "bsp_key_exti.h" #include "bsp_key_exti.h"
/* /*
****************************************************************** ******************************************************************
* *
****************************************************************** ******************************************************************
*/ */
uint16_t TimePerDiv_Group[] = {2, 5, 10, 20, 50, 100, 200, 500}; uint16_t TimePerDiv_Group[] = {2, 5, 10, 20, 50, 100, 200, 500};
uint8_t TimePerDiv_Nbr = sizeof(TimePerDiv_Group)/sizeof(TimePerDiv_Group[0]); uint8_t TimePerDiv_Nbr = sizeof(TimePerDiv_Group)/sizeof(TimePerDiv_Group[0]);
uint8_t TimePerDiv_Oder = 0; uint8_t TimePerDiv_Oder = 0;
//要显示的信息 //要显示的信息
FlagStatus Setting=RESET; FlagStatus Setting=RESET;
volatile uint16_t TimePerDiv = 1;//显示间隔时间长度 volatile uint16_t TimePerDiv = 1;//显示间隔时间长度
uint8_t TriggerMode = 1;//触发模式 uint8_t TriggerMode = 1;//触发模式
uint32_t TriggerValue = 1;//触发电平 uint32_t TriggerValue = 1;//触发电平
__IO uint16_t ADC_ConvertedValue[ADC_SampleNbr] = {0};//ADC采集数据 __IO uint16_t ADC_ConvertedValue[ADC_SampleNbr] = {0};//ADC采集数据
/* 定义线程控制块 */ /* 定义线程控制块 */
static rt_thread_t key_thread = RT_NULL; static rt_thread_t GetWave_thread = RT_NULL;
static rt_thread_t usart_thread = RT_NULL; static rt_thread_t PlotWave_thread = RT_NULL;
/* 定义消息队列控制块 */
rt_mq_t test_mq = RT_NULL;
/* 定义信号量控制块 */
rt_sem_t test_sem = RT_NULL; /************************* 全局变量声明 ****************************/
/*
/************************* 全局变量声明 ****************************/ *
/* */
*
*/ /* 相关宏定义 */
extern char Usart_Rx_Buf[USART_RBUFF_SIZE];
/* 相关宏定义 */
extern char Usart_Rx_Buf[USART_RBUFF_SIZE];
/*
************************************************************************* /*
* *************************************************************************
************************************************************************* * 线
*/ *************************************************************************
static void key_thread_entry(void* parameter); */
static void usart_thread_entry(void* parameter);
void PlotWave(void* parameter)
/* {
************************************************************************* uint16_t i;
* main LCD_SetColors(WHITE, BLACK);
************************************************************************* ILI9341_Clear(0,0,199,LCD_Y_LENGTH);
*/ for(i=0; i <= ADC_SampleNbr-2; i++)
/** {
* @brief LCD_SetTextColor(WHITE);
* @param ILI9341_DrawLine ( i, ADC_ConvertedValue[i] /21, i+1, ADC_ConvertedValue[i+1] /21 );
* @retval }
*/ }
int main(void)
{
//Init();
/* void Run(void)
* RTT系统初始化已经在main函数之前完成 {
* component.c文件中的rtthread_startup() GetWave_thread = /* 线程控制块指针 */
* main函数中线线 rt_thread_create( "GetWave", /* 线程名字 */
*/ ADCx_GetWaveData, /* 线程入口函数 */
rt_kprintf("这是一个[野火]-STM32F103-指南者-RTT中断管理实验\n"); RT_NULL, /* 线程入口函数参数 */
rt_kprintf("按下KEY1 | KEY2触发中断\n"); 512, /* 线程栈大小 */
rt_kprintf("串口发送数据触发中断,任务处理数据!\n"); 1, /* 线程的优先级 */
/* 创建一个消息队列 */ 20); /* 线程时间片 */
test_mq = rt_mq_create("test_mq",/* 消息队列名字 */
4, /* 消息的最大长度 */ /* 启动线程,开启调度 */
2, /* 消息队列的最大容量 */ if (GetWave_thread != RT_NULL)
RT_IPC_FLAG_FIFO);/* 队列模式 FIFO(0x00)*/ rt_thread_startup(GetWave_thread);
if (test_mq != RT_NULL)
rt_kprintf("消息队列创建成功!\n\n"); PlotWave_thread = /* 线程控制块指针 */
rt_thread_create( "PlotWave", /* 线程名字 */
/* 创建一个信号量 */ PlotWave, /* 线程入口函数 */
test_sem = rt_sem_create("test_sem",/* 消息队列名字 */ RT_NULL, /* 线程入口函数参数 */
0, /* 信号量初始值,默认有一个信号量 */ 512, /* 线程栈大小 */
RT_IPC_FLAG_FIFO); /* 信号量模式 FIFO(0x00)*/ 2, /* 线程的优先级 */
if (test_sem != RT_NULL) 20); /* 线程时间片 */
rt_kprintf("信号量创建成功!\n\n");
/* 启动线程,开启调度 */
/* 创建一个任务 */ if (PlotWave_thread != RT_NULL)
key_thread = /* 线程控制块指针 */ rt_thread_startup(PlotWave_thread);
rt_thread_create( "key", /* 线程名字 */ }
key_thread_entry, /* 线程入口函数 */
RT_NULL, /* 线程入口函数参数 */
512, /* 线程栈大小 */
1, /* 线程的优先级 */ /* ------------------------------------------end of file---------------------------------------- */
20); /* 线程时间片 */
/* 启动线程,开启调度 */
if (key_thread != RT_NULL)
rt_thread_startup(key_thread);
else
return -1;
usart_thread = /* 线程控制块指针 */
rt_thread_create( "usart", /* 线程名字 */
usart_thread_entry, /* 线程入口函数 */
RT_NULL, /* 线程入口函数参数 */
512, /* 线程栈大小 */
2, /* 线程的优先级 */
20); /* 线程时间片 */
/* 启动线程,开启调度 */
if (usart_thread != RT_NULL)
rt_thread_startup(usart_thread);
else
return -1;
}
/*
*************************************************************************
* 线
*************************************************************************
*/
static void key_thread_entry(void* parameter)
{
rt_err_t uwRet = RT_EOK;
uint32_t r_queue;
/* 任务都是一个无限循环,不能返回 */
while(1)
{
/* 队列读取(接收),等待时间为一直等待 */
uwRet = rt_mq_recv(test_mq, /* 读取接收队列的ID(句柄) */
&r_queue, /* 读取(接收)的数据保存位置 */
sizeof(r_queue), /* 读取(接收)的数据的长度 */
RT_WAITING_FOREVER); /* 等待时间:一直等 */
if(RT_EOK == uwRet)
{
rt_kprintf("触发中断的是KEY%d!\n",r_queue);
}
else
{
rt_kprintf("数据接收出错,错误代码: 0x%lx\n",uwRet);
}
LED1_TOGGLE;
}
}
static void usart_thread_entry(void* parameter)
{
rt_err_t uwRet = RT_EOK;
/* 任务都是一个无限循环,不能返回 */
while (1)
{
uwRet = rt_sem_take(test_sem, /* 获取串口中断的信号量 */
RT_WAITING_FOREVER); /* 等待时间0 */
if(RT_EOK == uwRet)
{
rt_kprintf("收到数据:%s\n",Usart_Rx_Buf);
memset(Usart_Rx_Buf,0,USART_RBUFF_SIZE);/* 清零 */
}
}
}
/* ------------------------------------------end of file---------------------------------------- */
void My_Delay(uint32_t nCount)
{
for( ; nCount > 0; nCount-- );
}
void PlotWave(void)
{
uint16_t i;
LCD_SetColors(WHITE, BLACK);
ILI9341_Clear(0,0,199,LCD_Y_LENGTH);
for(i=0; i <= ADC_SampleNbr-2; i++)
{
LCD_SetTextColor(WHITE);
ILI9341_DrawLine ( i, ADC_ConvertedValue[i] /21, i+1, ADC_ConvertedValue[i+1] /21 );
}
}
void Run(void)
{
key_thread = /* 线程控制块指针 */
rt_thread_create( "key", /* 线程名字 */
key_thread_entry, /* 线程入口函数 */
RT_NULL, /* 线程入口函数参数 */
512, /* 线程栈大小 */
1, /* 线程的优先级 */
20); /* 线程时间片 */
/* 启动线程,开启调度 */
if (key_thread != RT_NULL)
rt_thread_startup(key_thread);
ADCx_GetWaveData();
PlotWave();
}

View File

@ -1,24 +1,24 @@
#ifndef __OSC_H #ifndef __OSC_H
#define __OSC_H #define __OSC_H
#include "stm32f10x_it.h" #include "stm32f10x_it.h"
extern uint16_t TimePerDiv_Group[]; extern uint16_t TimePerDiv_Group[];
extern uint8_t TimePerDiv_Nbr; extern uint8_t TimePerDiv_Nbr;
extern uint8_t TimePerDiv_Oder; extern uint8_t TimePerDiv_Oder;
extern volatile uint16_t TimePerDiv; extern volatile uint16_t TimePerDiv;
extern uint8_t TriggerMode;//´¥·¢Ä£Ê½ extern uint8_t TriggerMode;//´¥·¢Ä£Ê½
extern uint32_t TriggerValue;//´¥·¢µçƽ extern uint32_t TriggerValue;//´¥·¢µçƽ
extern __IO uint16_t ADC_ConvertedValue[]; extern __IO uint16_t ADC_ConvertedValue[];
extern FlagStatus Setting; extern FlagStatus Setting;
void PlotWave(void); void PlotWave(void* parameter);
void Init(void); void Init(void);
void Run(void); void Run(void);
#endif /* __OSC_H */ #endif /* __OSC_H */

View File

@ -1,117 +1,117 @@
#include "bsp_adc.h" #include "bsp_adc.h"
#include "bsp_TiMbase.h" #include "bsp_TiMbase.h"
#include "OSC.h" #include "OSC.h"
//ADC IO端口初始化 //ADC IO端口初始化
static void ADCx_GPIO_Config(void) static void ADCx_GPIO_Config(void)
{ {
GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitTypeDef GPIO_InitStructure;
//开ADC IO端口时钟 //开ADC IO端口时钟
ADC_GPIO_APBxClock_FUN(ADC_GPIO_CLK, ENABLE); ADC_GPIO_APBxClock_FUN(ADC_GPIO_CLK, ENABLE);
//ADC IO引脚模式配置 //ADC IO引脚模式配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_InitStructure.GPIO_Pin = ADC_PIN; GPIO_InitStructure.GPIO_Pin = ADC_PIN;
GPIO_Init(ADC_PORT, &GPIO_InitStructure); GPIO_Init(ADC_PORT, &GPIO_InitStructure);
} }
//ADC模式配置 //ADC模式配置
static void ADCx_Mode_Config(void) static void ADCx_Mode_Config(void)
{ {
ADC_InitTypeDef ADC_InitStructure; ADC_InitTypeDef ADC_InitStructure;
ADC_APBxCLOCK_FUN(ADC_CLK, ENABLE); ADC_APBxCLOCK_FUN(ADC_CLK, ENABLE);
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = DISABLE; ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1; ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC_x, &ADC_InitStructure); ADC_Init(ADC_x, &ADC_InitStructure);
RCC_ADCCLKConfig(RCC_PCLK2_Div6);//12MHz RCC_ADCCLKConfig(RCC_PCLK2_Div6);//12MHz
ADC_RegularChannelConfig(ADC_x, ADC_CHANNEL, 1, ADC_SampleTime_71Cycles5);//转换时间7us ADC_RegularChannelConfig(ADC_x, ADC_CHANNEL, 1, ADC_SampleTime_71Cycles5);//转换时间7us
ADC_ITConfig(ADC_x, ADC_IT_EOC, ENABLE); ADC_ITConfig(ADC_x, ADC_IT_EOC, ENABLE);
ADC_Cmd(ADC_x, ENABLE); ADC_Cmd(ADC_x, ENABLE);
// ADC开始校准 // ADC开始校准
ADC_StartCalibration(ADC_x); ADC_StartCalibration(ADC_x);
// 等待校准完成 // 等待校准完成
while(ADC_GetCalibrationStatus(ADC_x)); while(ADC_GetCalibrationStatus(ADC_x));
ADC_SoftwareStartConvCmd(ADC_x, ENABLE); ADC_SoftwareStartConvCmd(ADC_x, ENABLE);
} }
//static void ADCx_NVIC_Config(void) //static void ADCx_NVIC_Config(void)
//{ //{
// NVIC_InitTypeDef NVIC_InitStructure; // NVIC_InitTypeDef NVIC_InitStructure;
// //优先级分组 // //优先级分组
// NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); // NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
// //
// NVIC_InitStructure.NVIC_IRQChannel = ADC_IRQ; // NVIC_InitStructure.NVIC_IRQChannel = ADC_IRQ;
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
// NVIC_Init(&NVIC_InitStructure); // NVIC_Init(&NVIC_InitStructure);
//} //}
void ADCx_Init(void) void ADCx_Init(void)
{ {
//ADCx_NVIC_Config(); //ADCx_NVIC_Config();
ADCx_GPIO_Config(); ADCx_GPIO_Config();
ADCx_Mode_Config(); ADCx_Mode_Config();
} }
FlagStatus Get_Trigger_Status(void) FlagStatus Get_Trigger_Status(void)
{ {
uint16_t d0, d1; uint16_t d0, d1;
while(ADC_GetITStatus(ADC_x, ADC_IT_EOC) == RESET); while(ADC_GetITStatus(ADC_x, ADC_IT_EOC) == RESET);
d0 = ADC_GetConversionValue(ADC_x); d0 = ADC_GetConversionValue(ADC_x);
ADC_ClearITPendingBit(ADC_x, ADC_IT_EOC); ADC_ClearITPendingBit(ADC_x, ADC_IT_EOC);
while(ADC_GetITStatus(ADC_x, ADC_IT_EOC) == RESET); while(ADC_GetITStatus(ADC_x, ADC_IT_EOC) == RESET);
d1 = ADC_GetConversionValue(ADC_x); d1 = ADC_GetConversionValue(ADC_x);
ADC_ClearITPendingBit(ADC_x, ADC_IT_EOC); ADC_ClearITPendingBit(ADC_x, ADC_IT_EOC);
if(TriggerMode == 1) if(TriggerMode == 1)
{ {
if(d1 - d0 > TriggerValue) if(d1 - d0 > TriggerValue)
return SET; return SET;
} }
else if(TriggerMode == 0) else if(TriggerMode == 0)
{ {
if(d0 - d1 > TriggerValue) if(d0 - d1 > TriggerValue)
return SET; return SET;
} }
return RESET; return RESET;
} }
void ADCx_GetWaveData(void) void ADCx_GetWaveData(void* parameter)
{ {
uint16_t ADC_SampleCount=0; uint16_t ADC_SampleCount=0;
while(Get_Trigger_Status() == RESET); while(Get_Trigger_Status() == RESET);
while(ADC_SampleCount < ADC_SampleNbr) while(ADC_SampleCount < ADC_SampleNbr)
{ {
while(ADC_GetITStatus(ADC_x, ADC_IT_EOC) != SET); while(ADC_GetITStatus(ADC_x, ADC_IT_EOC) != SET);
ADC_ConvertedValue[ADC_SampleCount] = ADC_GetConversionValue(ADC_x); ADC_ConvertedValue[ADC_SampleCount] = ADC_GetConversionValue(ADC_x);
ADC_ClearITPendingBit(ADC_x, ADC_IT_EOC); ADC_ClearITPendingBit(ADC_x, ADC_IT_EOC);
Delay_us( TimePerDiv*1000/50 -7 ); Delay_us( TimePerDiv*1000/50 -7 );
ADC_SampleCount++; ADC_SampleCount++;
} }
} }

View File

@ -1,33 +1,33 @@
#ifndef __BSP_ADC_H #ifndef __BSP_ADC_H
#define __BSP_ADC_H #define __BSP_ADC_H
#include "stm32f10x.h" #include "stm32f10x.h"
//采样点数 //采样点数
#define ADC_SampleNbr 200 #define ADC_SampleNbr 200
//ADC GPIO宏定义 不能使用复用引脚 //ADC GPIO宏定义 不能使用复用引脚
#define ADC_GPIO_APBxClock_FUN RCC_APB2PeriphClockCmd #define ADC_GPIO_APBxClock_FUN RCC_APB2PeriphClockCmd
#define ADC_GPIO_CLK RCC_APB2Periph_GPIOC #define ADC_GPIO_CLK RCC_APB2Periph_GPIOC
#define ADC_PORT GPIOC #define ADC_PORT GPIOC
#define ADC_PIN GPIO_Pin_1 #define ADC_PIN GPIO_Pin_1
//ADC编号选择 可以是 ADC1/2如果使用ADC3中断相关的要改成ADC3的时钟也不同 //ADC编号选择 可以是 ADC1/2如果使用ADC3中断相关的要改成ADC3的时钟也不同
#define ADC_APBxCLOCK_FUN RCC_APB2PeriphClockCmd #define ADC_APBxCLOCK_FUN RCC_APB2PeriphClockCmd
#define ADC_x ADC2 #define ADC_x ADC2
#define ADC_CLK RCC_APB2Periph_ADC2 #define ADC_CLK RCC_APB2Periph_ADC2
//ADC通道宏定义 //ADC通道宏定义
#define ADC_CHANNEL ADC_Channel_11 #define ADC_CHANNEL ADC_Channel_11
//ADC中断相关宏 //ADC中断相关宏
#define ADC_IRQ ADC1_2_IRQn #define ADC_IRQ ADC1_2_IRQn
#define ADC_IRQHandler ADC1_2_IRQHandler #define ADC_IRQHandler ADC1_2_IRQHandler
void ADCx_Init(void); void ADCx_Init(void);
FlagStatus Get_Trigger_Status(void); FlagStatus Get_Trigger_Status(void);
void ADCx_GetWaveData(void); void ADCx_GetWaveData(void* parameter);
#endif /* __BSP_ADC_H */ #endif /* __BSP_ADC_H */

View File

@ -1,155 +1,23 @@
#include "board.h"
#include "rtthread.h" /*
#include <string.h> *************************************************************************
* main
*************************************************************************
*/
/**
/* * @brief
****************************************************************** * @param
* * @retval
****************************************************************** */
*/ int main(void)
/* 定义线程控制块 */ {
static rt_thread_t key_thread = RT_NULL;
static rt_thread_t usart_thread = RT_NULL; }
/* 定义消息队列控制块 */
rt_mq_t test_mq = RT_NULL;
/* 定义信号量控制块 */
rt_sem_t test_sem = RT_NULL;
/************************* 全局变量声明 ****************************/
/* /* ------------------------------------------end of file---------------------------------------- */
*
*/
/* 相关宏定义 */
extern char Usart_Rx_Buf[USART_RBUFF_SIZE];
/*
*************************************************************************
*
*************************************************************************
*/
static void key_thread_entry(void* parameter);
static void usart_thread_entry(void* parameter);
/*
*************************************************************************
* main
*************************************************************************
*/
/**
* @brief
* @param
* @retval
*/
int main(void)
{
//Init();
/*
* RTT系统初始化已经在main函数之前完成
* component.c文件中的rtthread_startup()
* main函数中线线
*/
rt_kprintf("这是一个[野火]-STM32F103-指南者-RTT中断管理实验\n");
rt_kprintf("按下KEY1 | KEY2触发中断\n");
rt_kprintf("串口发送数据触发中断,任务处理数据!\n");
/* 创建一个消息队列 */
test_mq = rt_mq_create("test_mq",/* 消息队列名字 */
4, /* 消息的最大长度 */
2, /* 消息队列的最大容量 */
RT_IPC_FLAG_FIFO);/* 队列模式 FIFO(0x00)*/
if (test_mq != RT_NULL)
rt_kprintf("消息队列创建成功!\n\n");
/* 创建一个信号量 */
test_sem = rt_sem_create("test_sem",/* 消息队列名字 */
0, /* 信号量初始值,默认有一个信号量 */
RT_IPC_FLAG_FIFO); /* 信号量模式 FIFO(0x00)*/
if (test_sem != RT_NULL)
rt_kprintf("信号量创建成功!\n\n");
/* 创建一个任务 */
key_thread = /* 线程控制块指针 */
rt_thread_create( "key", /* 线程名字 */
key_thread_entry, /* 线程入口函数 */
RT_NULL, /* 线程入口函数参数 */
512, /* 线程栈大小 */
1, /* 线程的优先级 */
20); /* 线程时间片 */
/* 启动线程,开启调度 */
if (key_thread != RT_NULL)
rt_thread_startup(key_thread);
else
return -1;
usart_thread = /* 线程控制块指针 */
rt_thread_create( "usart", /* 线程名字 */
usart_thread_entry, /* 线程入口函数 */
RT_NULL, /* 线程入口函数参数 */
512, /* 线程栈大小 */
2, /* 线程的优先级 */
20); /* 线程时间片 */
/* 启动线程,开启调度 */
if (usart_thread != RT_NULL)
rt_thread_startup(usart_thread);
else
return -1;
}
/*
*************************************************************************
* 线
*************************************************************************
*/
static void key_thread_entry(void* parameter)
{
rt_err_t uwRet = RT_EOK;
uint32_t r_queue;
/* 任务都是一个无限循环,不能返回 */
while(1)
{
/* 队列读取(接收),等待时间为一直等待 */
uwRet = rt_mq_recv(test_mq, /* 读取接收队列的ID(句柄) */
&r_queue, /* 读取(接收)的数据保存位置 */
sizeof(r_queue), /* 读取(接收)的数据的长度 */
RT_WAITING_FOREVER); /* 等待时间:一直等 */
if(RT_EOK == uwRet)
{
rt_kprintf("触发中断的是KEY%d!\n",r_queue);
}
else
{
rt_kprintf("数据接收出错,错误代码: 0x%lx\n",uwRet);
}
LED1_TOGGLE;
}
}
static void usart_thread_entry(void* parameter)
{
rt_err_t uwRet = RT_EOK;
/* 任务都是一个无限循环,不能返回 */
while (1)
{
uwRet = rt_sem_take(test_sem, /* 获取串口中断的信号量 */
RT_WAITING_FOREVER); /* 等待时间0 */
if(RT_EOK == uwRet)
{
rt_kprintf("收到数据:%s\n",Usart_Rx_Buf);
memset(Usart_Rx_Buf,0,USART_RBUFF_SIZE);/* 清零 */
}
}
}
/* ------------------------------------------end of file---------------------------------------- */

View File

@ -1,245 +1,245 @@
/** /**
****************************************************************************** ******************************************************************************
* @file bsp_usart.c * @file bsp_usart.c
* @author fire * @author fire
* @version V1.0 * @version V1.0
* @date 2013-xx-xx * @date 2013-xx-xx
* @brief c库printf函数到usart端口 * @brief c库printf函数到usart端口
****************************************************************************** ******************************************************************************
* @attention * @attention
* *
* :STM32 F103- * :STM32 F103-
* :http://www.firebbs.cn * :http://www.firebbs.cn
* :https://fire-stm32.taobao.com * :https://fire-stm32.taobao.com
* *
****************************************************************************** ******************************************************************************
*/ */
#include "bsp_usart.h" #include "bsp_usart.h"
#include "rtthread.h" #include "rtthread.h"
/* 外部定义信号量控制块 */ /* 外部定义信号量控制块 */
extern rt_sem_t test_sem; extern rt_sem_t test_sem;
/** /**
* @brief NVIC * @brief NVIC
* @param * @param
* @retval * @retval
*/ */
static void NVIC_Configuration(void) static void NVIC_Configuration(void)
{ {
NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitTypeDef NVIC_InitStructure;
/* 嵌套向量中断控制器组选择 */ /* 嵌套向量中断控制器组选择 */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
/* 配置USART为中断源 */ /* 配置USART为中断源 */
NVIC_InitStructure.NVIC_IRQChannel = DEBUG_USART_IRQ; NVIC_InitStructure.NVIC_IRQChannel = DEBUG_USART_IRQ;
/* 抢断优先级*/ /* 抢断优先级*/
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
/* 子优先级 */ /* 子优先级 */
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
/* 使能中断 */ /* 使能中断 */
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
/* 初始化配置NVIC */ /* 初始化配置NVIC */
NVIC_Init(&NVIC_InitStructure); NVIC_Init(&NVIC_InitStructure);
} }
/** /**
* @brief USART GPIO , * @brief USART GPIO ,
* @param * @param
* @retval * @retval
*/ */
void USART_Config(void) void USART_Config(void)
{ {
GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure; USART_InitTypeDef USART_InitStructure;
// 打开串口GPIO的时钟 // 打开串口GPIO的时钟
DEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK, ENABLE); DEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK, ENABLE);
// 打开串口外设的时钟 // 打开串口外设的时钟
DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK, ENABLE); DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK, ENABLE);
// 将USART Tx的GPIO配置为推挽复用模式 // 将USART Tx的GPIO配置为推挽复用模式
GPIO_InitStructure.GPIO_Pin = DEBUG_USART_TX_GPIO_PIN; GPIO_InitStructure.GPIO_Pin = DEBUG_USART_TX_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStructure); GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStructure);
// 将USART Rx的GPIO配置为浮空输入模式 // 将USART Rx的GPIO配置为浮空输入模式
GPIO_InitStructure.GPIO_Pin = DEBUG_USART_RX_GPIO_PIN; GPIO_InitStructure.GPIO_Pin = DEBUG_USART_RX_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure); GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure);
// 配置串口的工作参数 // 配置串口的工作参数
// 配置波特率 // 配置波特率
USART_InitStructure.USART_BaudRate = DEBUG_USART_BAUDRATE; USART_InitStructure.USART_BaudRate = DEBUG_USART_BAUDRATE;
// 配置 针数据字长 // 配置 针数据字长
USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_WordLength = USART_WordLength_8b;
// 配置停止位 // 配置停止位
USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_StopBits = USART_StopBits_1;
// 配置校验位 // 配置校验位
USART_InitStructure.USART_Parity = USART_Parity_No ; USART_InitStructure.USART_Parity = USART_Parity_No ;
// 配置硬件流控制 // 配置硬件流控制
USART_InitStructure.USART_HardwareFlowControl = USART_InitStructure.USART_HardwareFlowControl =
USART_HardwareFlowControl_None; USART_HardwareFlowControl_None;
// 配置工作模式,收发一起 // 配置工作模式,收发一起
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
// 完成串口的初始化配置 // 完成串口的初始化配置
USART_Init(DEBUG_USARTx, &USART_InitStructure); USART_Init(DEBUG_USARTx, &USART_InitStructure);
// 串口中断优先级配置 // 串口中断优先级配置
NVIC_Configuration(); NVIC_Configuration();
// 开启 串口空闲IDEL 中断 // 开启 串口空闲IDEL 中断
USART_ITConfig(DEBUG_USARTx, USART_IT_IDLE, ENABLE); USART_ITConfig(DEBUG_USARTx, USART_IT_IDLE, ENABLE);
// 开启串口DMA接收 // 开启串口DMA接收
USART_DMACmd(DEBUG_USARTx, USART_DMAReq_Rx, ENABLE); USART_DMACmd(DEBUG_USARTx, USART_DMAReq_Rx, ENABLE);
// 使能串口 // 使能串口
USART_Cmd(DEBUG_USARTx, ENABLE); USART_Cmd(DEBUG_USARTx, ENABLE);
} }
char Usart_Rx_Buf[USART_RBUFF_SIZE]; char Usart_Rx_Buf[USART_RBUFF_SIZE];
void USARTx_DMA_Config(void) void USARTx_DMA_Config(void)
{ {
DMA_InitTypeDef DMA_InitStructure; DMA_InitTypeDef DMA_InitStructure;
// 开启DMA时钟 // 开启DMA时钟
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
// 设置DMA源地址串口数据寄存器地址*/ // 设置DMA源地址串口数据寄存器地址*/
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)USART_DR_ADDRESS; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)USART_DR_ADDRESS;
// 内存地址(要传输的变量的指针) // 内存地址(要传输的变量的指针)
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)Usart_Rx_Buf; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)Usart_Rx_Buf;
// 方向:从内存到外设 // 方向:从内存到外设
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
// 传输大小 // 传输大小
DMA_InitStructure.DMA_BufferSize = USART_RBUFF_SIZE; DMA_InitStructure.DMA_BufferSize = USART_RBUFF_SIZE;
// 外设地址不增 // 外设地址不增
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
// 内存地址自增 // 内存地址自增
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
// 外设数据单位 // 外设数据单位
DMA_InitStructure.DMA_PeripheralDataSize = DMA_InitStructure.DMA_PeripheralDataSize =
DMA_PeripheralDataSize_Byte; DMA_PeripheralDataSize_Byte;
// 内存数据单位 // 内存数据单位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
// DMA模式一次或者循环模式 // DMA模式一次或者循环模式
//DMA_InitStructure.DMA_Mode = DMA_Mode_Normal ; //DMA_InitStructure.DMA_Mode = DMA_Mode_Normal ;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
// 优先级:中 // 优先级:中
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
// 禁止内存到内存的传输 // 禁止内存到内存的传输
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
// 配置DMA通道 // 配置DMA通道
DMA_Init(USART_RX_DMA_CHANNEL, &DMA_InitStructure); DMA_Init(USART_RX_DMA_CHANNEL, &DMA_InitStructure);
// 清除DMA所有标志 // 清除DMA所有标志
DMA_ClearFlag(DMA1_FLAG_GL5); DMA_ClearFlag(DMA1_FLAG_GL5);
DMA_ITConfig(USART_RX_DMA_CHANNEL, DMA_IT_TE, ENABLE); DMA_ITConfig(USART_RX_DMA_CHANNEL, DMA_IT_TE, ENABLE);
// 使能DMA // 使能DMA
DMA_Cmd (USART_RX_DMA_CHANNEL,ENABLE); DMA_Cmd (USART_RX_DMA_CHANNEL,ENABLE);
} }
void Uart_DMA_Rx_Data(void) void Uart_DMA_Rx_Data(void)
{ {
// 关闭DMA ,防止干扰 // 关闭DMA ,防止干扰
DMA_Cmd(USART_RX_DMA_CHANNEL, DISABLE); DMA_Cmd(USART_RX_DMA_CHANNEL, DISABLE);
// 清DMA标志位 // 清DMA标志位
DMA_ClearFlag( DMA1_FLAG_GL5 ); DMA_ClearFlag( DMA1_FLAG_GL5 );
// 重新赋值计数值,必须大于等于最大可能接收到的数据帧数目 // 重新赋值计数值,必须大于等于最大可能接收到的数据帧数目
USART_RX_DMA_CHANNEL->CNDTR = USART_RBUFF_SIZE; USART_RX_DMA_CHANNEL->CNDTR = USART_RBUFF_SIZE;
DMA_Cmd(USART_RX_DMA_CHANNEL, ENABLE); DMA_Cmd(USART_RX_DMA_CHANNEL, ENABLE);
//给出二值信号量 ,发送接收到新数据标志,供前台程序查询 //给出二值信号量 ,发送接收到新数据标志,供前台程序查询
rt_sem_release(test_sem); //rt_sem_release(test_sem);
/* /*
DMA MCU来不及处理此次接收到的数据 DMA MCU来不及处理此次接收到的数据
2 2
1. DMA通道之前LumMod_Rx_Buf缓冲区里面的数据复制到另外一个数组中 1. DMA通道之前LumMod_Rx_Buf缓冲区里面的数据复制到另外一个数组中
DMA DMA
2. LumMod_Uart_DMA_Rx_Data函数中DMA_MemoryBaseAddr 2. LumMod_Uart_DMA_Rx_Data函数中DMA_MemoryBaseAddr
*/ */
} }
/***************** 发送一个字节 **********************/ /***************** 发送一个字节 **********************/
void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch) void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch)
{ {
/* 发送一个字节数据到USART */ /* 发送一个字节数据到USART */
USART_SendData(pUSARTx,ch); USART_SendData(pUSARTx,ch);
/* 等待发送数据寄存器为空 */ /* 等待发送数据寄存器为空 */
while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET); while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
} }
/****************** 发送8位的数组 ************************/ /****************** 发送8位的数组 ************************/
void Usart_SendArray( USART_TypeDef * pUSARTx, uint8_t *array, uint16_t num) void Usart_SendArray( USART_TypeDef * pUSARTx, uint8_t *array, uint16_t num)
{ {
uint8_t i; uint8_t i;
for(i=0; i<num; i++) for(i=0; i<num; i++)
{ {
/* 发送一个字节数据到USART */ /* 发送一个字节数据到USART */
Usart_SendByte(pUSARTx,array[i]); Usart_SendByte(pUSARTx,array[i]);
} }
/* 等待发送完成 */ /* 等待发送完成 */
while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET); while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET);
} }
/***************** 发送字符串 **********************/ /***************** 发送字符串 **********************/
void Usart_SendString( USART_TypeDef * pUSARTx, char *str) void Usart_SendString( USART_TypeDef * pUSARTx, char *str)
{ {
unsigned int k=0; unsigned int k=0;
do do
{ {
Usart_SendByte( pUSARTx, *(str + k) ); Usart_SendByte( pUSARTx, *(str + k) );
k++; k++;
} while(*(str + k)!='\0'); } while(*(str + k)!='\0');
/* 等待发送完成 */ /* 等待发送完成 */
while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET) while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET)
{} {}
} }
/***************** 发送一个16位数 **********************/ /***************** 发送一个16位数 **********************/
void Usart_SendHalfWord( USART_TypeDef * pUSARTx, uint16_t ch) void Usart_SendHalfWord( USART_TypeDef * pUSARTx, uint16_t ch)
{ {
uint8_t temp_h, temp_l; uint8_t temp_h, temp_l;
/* 取出高八位 */ /* 取出高八位 */
temp_h = (ch&0XFF00)>>8; temp_h = (ch&0XFF00)>>8;
/* 取出低八位 */ /* 取出低八位 */
temp_l = ch&0XFF; temp_l = ch&0XFF;
/* 发送高八位 */ /* 发送高八位 */
USART_SendData(pUSARTx,temp_h); USART_SendData(pUSARTx,temp_h);
while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET); while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
/* 发送低八位 */ /* 发送低八位 */
USART_SendData(pUSARTx,temp_l); USART_SendData(pUSARTx,temp_l);
while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET); while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
} }
///重定向c库函数printf到串口重定向后可使用printf函数 ///重定向c库函数printf到串口重定向后可使用printf函数
int fputc(int ch, FILE *f) int fputc(int ch, FILE *f)
{ {
/* 发送一个字节数据到串口 */ /* 发送一个字节数据到串口 */
USART_SendData(DEBUG_USARTx, (uint8_t) ch); USART_SendData(DEBUG_USARTx, (uint8_t) ch);
/* 等待发送完毕 */ /* 等待发送完毕 */
while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE) == RESET); while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE) == RESET);
return (ch); return (ch);
} }
///重定向c库函数scanf到串口重写向后可使用scanf、getchar等函数 ///重定向c库函数scanf到串口重写向后可使用scanf、getchar等函数
int fgetc(FILE *f) int fgetc(FILE *f)
{ {
/* 等待串口输入数据 */ /* 等待串口输入数据 */
while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_RXNE) == RESET); while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_RXNE) == RESET);
return (int)USART_ReceiveData(DEBUG_USARTx); return (int)USART_ReceiveData(DEBUG_USARTx);
} }