创建显示线程

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>
<FileNumber>36</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExp>1</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>..\User\OSC\OSC.c</PathWithFileName>

View File

@ -1,213 +1,100 @@
#include "rtthread.h"
#include "OSC.h"
#include "stm32f10x.h"
#include "bsp_ili9341_lcd.h"
#include "bsp_usart.h"
#include "bsp_adc.h"
#include "bsp_led.h"
#include "bsp_TiMbase.h"
#include "bsp_key_exti.h"
/*
******************************************************************
*
******************************************************************
*/
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_Oder = 0;
//要显示的信息
FlagStatus Setting=RESET;
volatile uint16_t TimePerDiv = 1;//显示间隔时间长度
uint8_t TriggerMode = 1;//触发模式
uint32_t TriggerValue = 1;//触发电平
__IO uint16_t ADC_ConvertedValue[ADC_SampleNbr] = {0};//ADC采集数据
/* 定义线程控制块 */
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;
/************************* 全局变量声明 ****************************/
/*
*
*/
/* 相关宏定义 */
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---------------------------------------- */
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();
}
#include "rtthread.h"
#include "OSC.h"
#include "stm32f10x.h"
#include "bsp_ili9341_lcd.h"
#include "bsp_usart.h"
#include "bsp_adc.h"
#include "bsp_led.h"
#include "bsp_TiMbase.h"
#include "bsp_key_exti.h"
/*
******************************************************************
*
******************************************************************
*/
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_Oder = 0;
//要显示的信息
FlagStatus Setting=RESET;
volatile uint16_t TimePerDiv = 1;//显示间隔时间长度
uint8_t TriggerMode = 1;//触发模式
uint32_t TriggerValue = 1;//触发电平
__IO uint16_t ADC_ConvertedValue[ADC_SampleNbr] = {0};//ADC采集数据
/* 定义线程控制块 */
static rt_thread_t GetWave_thread = RT_NULL;
static rt_thread_t PlotWave_thread = RT_NULL;
/************************* 全局变量声明 ****************************/
/*
*
*/
/* 相关宏定义 */
extern char Usart_Rx_Buf[USART_RBUFF_SIZE];
/*
*************************************************************************
* 线
*************************************************************************
*/
void PlotWave(void* parameter)
{
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)
{
GetWave_thread = /* 线程控制块指针 */
rt_thread_create( "GetWave", /* 线程名字 */
ADCx_GetWaveData, /* 线程入口函数 */
RT_NULL, /* 线程入口函数参数 */
512, /* 线程栈大小 */
1, /* 线程的优先级 */
20); /* 线程时间片 */
/* 启动线程,开启调度 */
if (GetWave_thread != RT_NULL)
rt_thread_startup(GetWave_thread);
PlotWave_thread = /* 线程控制块指针 */
rt_thread_create( "PlotWave", /* 线程名字 */
PlotWave, /* 线程入口函数 */
RT_NULL, /* 线程入口函数参数 */
512, /* 线程栈大小 */
2, /* 线程的优先级 */
20); /* 线程时间片 */
/* 启动线程,开启调度 */
if (PlotWave_thread != RT_NULL)
rt_thread_startup(PlotWave_thread);
}
/* ------------------------------------------end of file---------------------------------------- */

View File

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

View File

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

View File

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

View File

@ -1,155 +1,23 @@
#include "board.h"
#include "rtthread.h"
#include <string.h>
/*
******************************************************************
*
******************************************************************
*/
/* 定义线程控制块 */
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;
/************************* 全局变量声明 ****************************/
/*
*
*/
/* 相关宏定义 */
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---------------------------------------- */
/*
*************************************************************************
* main
*************************************************************************
*/
/**
* @brief
* @param
* @retval
*/
int main(void)
{
}
/* ------------------------------------------end of file---------------------------------------- */

View File

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