小猫爪:嵌入式小知识08-KEIL/IAR FLASH算法_小猫爪的博客-CSDN博客
ps:3rd_part 第三方软件
外设寄存器访问示例
寄存器读 i = ADC1-> ctrl1;
寄存器写 ADC1-> ctrl1 = i;
bit 5 按位域方式读 i = ADC1-> ctrl1. cceien;
bit 5 按位域方式写 1 ADC1-> ctrl1. cceien= TRUE;
bit 5 直接写 1 ADC1-> ctrl1 |= 1 ctrl1&= ~(1<<5) ;
DAC的配置:
系统时钟:
在调试例程时,使用的是DAC1,DAC1的DMA是固定映射在DMA2通道的ch3通道的,
但是例程中使用的是DMA1的CH1通道。
通过手册知道这里亚特力的DMA弹性映射,DMA 弹性映射请求功能提供了一种更灵活的使用方式,即外设的 DMA 通道不固定,可选择 DMA1 和 DMA2 中,共 14 个通道的任意一个通道。DMA 弹性映射请求功能提供了一种更灵活的使用方式,即外设的 DMA 通道不固定,可选择 DMA1 和 DMA2 中,共 14 个通道的任意一个通道。可以将某外设的 DMA 请求通道指定到 DMA1 或者 DMA2 共 14 个通道中的任意一个通道。(如:可以将 SPI1 接受数据的 DMA 请求指定到 DMA1 的通道 7)。
dma_flexible_config(DMA1, FLEX_CHANNEL1, DMA_FLEXIBLE_DAC2);
//此处即将固定映射在DMA2\CH4上的DAC2的DMA通道弹性映射到DMA1的CH1通道
参考文章:STM32学习-DMA介绍及一般使用方法_Yahong.W的博客-CSDN博客_stm32 dma
ps:DMA配置流程
实验:ADC+DMA生成基波为10Khz的方波的三角波;
#include "at32f403a_407_board.h"
#include "at32f403a_407_clock.h"
/** @addtogroup AT32F407_periph_examples
* @{
*/
/** @addtogroup 407_DAC_double_mode_dma_sinewave DAC_double_mode_dma_sinewave
* @{
*/
gpio_init_type gpio_init_struct = {0};
dma_init_type dma_init_struct = {0};
crm_clocks_freq_type crm_clocks_freq_struct = {0};
uint16_t square[512];
uint32_t dualsine12bit[512];
uint32_t idx = 0;
/**
* @brief main function.
* @param none
* @retval none
*/
int main(void)
{
system_clock_config();
at32_board_init();
/* turn led2/led3/led4 on */
at32_led_on(LED2);
at32_led_on(LED3);
at32_led_on(LED4);
/* enable dac/tmr2/gpioa clock */
crm_periph_clock_enable(CRM_DMA1_PERIPH_CLOCK, TRUE);
crm_periph_clock_enable(CRM_DAC_PERIPH_CLOCK, TRUE);
crm_periph_clock_enable(CRM_TMR2_PERIPH_CLOCK, TRUE);
crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
/* once the dac is enabled, the corresponding gpio pin is automatically
connected to the dac converter. in order to avoid parasitic consumption,
the gpio pin should be configured in analog */
gpio_init_struct.gpio_pins = GPIO_PINS_4 | GPIO_PINS_5;
gpio_init_struct.gpio_mode = GPIO_MODE_ANALOG;
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
gpio_init(GPIOA, &gpio_init_struct);
/* get system clock */
crm_clocks_freq_get(&crm_clocks_freq_struct);
/* (systemclock/(systemclock/1000000))/100 = 10KHz */
tmr_base_init(TMR2, 99, (crm_clocks_freq_struct.sclk_freq/1000000 - 1));
tmr_cnt_dir_set(TMR2, TMR_COUNT_UP);
/* primary tmr2 output selection */
tmr_primary_mode_select(TMR2, TMR_PRIMARY_SEL_OVERFLOW);
/* dac1 and dac2 configuration */
dac_trigger_select(DAC1_SELECT, DAC_TMR2_TRGOUT_EVENT);
dac_trigger_select(DAC2_SELECT, DAC_TMR2_TRGOUT_EVENT);
dac_trigger_enable(DAC1_SELECT, TRUE);
dac_trigger_enable(DAC2_SELECT, TRUE);
dac_wave_generate(DAC1_SELECT, DAC_WAVE_GENERATE_NONE);
dac_wave_generate(DAC2_SELECT, DAC_WAVE_GENERATE_NONE);
dac_output_buffer_enable(DAC1_SELECT, FALSE);
dac_output_buffer_enable(DAC2_SELECT, FALSE);
dac_dma_enable(DAC1_SELECT, TRUE);
dac_dma_enable(DAC2_SELECT, TRUE);
/* fill sine32bit table */
for(idx = 0; idx < 256; idx++)
{
square[2*idx] = (4095-idx*8);
square[2*idx+1] = idx * 8;
}
for(idx = 0; idx < 512; idx++)
{
dualsine12bit[idx] = (square[idx] << 16) + (square[idx]);
}
/* dma1 channel1 configuration */
dma_reset(DMA1_CHANNEL1);
dma_init_struct.buffer_size = 512;
dma_init_struct.direction = DMA_DIR_MEMORY_TO_PERIPHERAL;
dma_init_struct.memory_base_addr = (uint32_t)dualsine12bit;
dma_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_WORD;
dma_init_struct.memory_inc_enable = TRUE;
dma_init_struct.peripheral_base_addr = (uint32_t)0x40007420;
dma_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_WORD;
dma_init_struct.peripheral_inc_enable = FALSE;
dma_init_struct.priority = DMA_PRIORITY_MEDIUM;
dma_init_struct.loop_mode_enable = TRUE;
dma_init(DMA1_CHANNEL1, &dma_init_struct);
/* enable dma flexible function */
dma_flexible_config(DMA1, FLEX_CHANNEL1, DMA_FLEXIBLE_DAC1);
dma_channel_enable(DMA1_CHANNEL1, TRUE);
/* enable dac1: once the dac1 is enabled, pa.04 is
automatically connected to the dac converter. */
dac_enable(DAC1_SELECT, TRUE);
/* enable dac2: once the dac2 is enabled, pa.05 is
automatically connected to the dac converter. */
dac_enable(DAC2_SELECT, TRUE);
/* enable tmr2 */
tmr_counter_enable(TMR2, TRUE);
while(1)
{
}
}
参考文章:stm32与GPS模块的数据传输,最后把数据传回到电脑上_追梦者( '▿ ' )的博客-CSDN博客_g28z2fttl 需要插卡吗
拾取坐标系统
/**
**************************************************************************
* @file main.c
* @brief main program
*Read GPS information through seral port2 and prin out the information
*through serial port1
**************************************************************************
*/
#include "at32f403a_407_board.h"
#include "at32f403a_407_clock.h"
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "stdbool.h "
typedef struct Data
{
char GPS_Buffer[200];//数据接收
bool isGetData;//接收数据是否完成
char *UTCTime;//时间戳
char *latitude;//纬度
char *N_S;//南北
char *longitude;//经度
char *E_W;//东西
bool isParseData;//是否解析完成
bool isUsefull;//是否为有效数据位
}Data;
short int point1;
const short int USART2_MAX_RECV_LEN = 200;
char USAR2_RX_BUF[USART2_MAX_RECV_LEN];
const short int GPS_Buffer_Length = 200;
struct Data Save_Data;
/**
* @brief initialize uart1
* @param baudrate: uart baudrate
* @retval none
*/
void uart1_print_init(uint32_t baudrate)
{
gpio_init_type gpio_init_struct;
#if defined (__GNUC__) && !defined (__clang__)
setvbuf(stdout, NULL, _IONBF, 0);
#endif
/* enable the uart and gpio clock */
crm_periph_clock_enable(CRM_USART1_PERIPH_CLOCK, TRUE);
crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
gpio_default_para_init(&gpio_init_struct);
/* configure the uart tx pin */
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
gpio_init_struct.gpio_pins = GPIO_PINS_9;
gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
gpio_init(GPIOA, &gpio_init_struct);
/* configure uart param */
usart_init(USART1, baudrate, USART_DATA_8BITS, USART_STOP_1_BIT);
usart_transmitter_enable(USART1, TRUE);
usart_enable(USART1, TRUE);
}
/**
* @brief initialize uart2 RX:PA3 TX:PA2
* @param baudrate: uart baudrate
* @retyal none
*/
void uart2_receive_init(uint32_t baudrate)
{
gpio_init_type gpio_init_struct;
/* enable the uart and gpio clock*/
crm_periph_clock_enable(CRM_USART2_PERIPH_CLOCK,TRUE);
crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK,TRUE);
gpio_default_para_init(&gpio_init_struct);
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
gpio_init_struct.gpio_mode = GPIO_MODE_INPUT;
gpio_init_struct.gpio_pins = GPIO_PINS_3;
gpio_init_struct.gpio_pull = GPIO_PULL_UP;
gpio_init(GPIOA,&gpio_init_struct);
usart_init(USART2,baudrate,USART_DATA_8BITS,USART_STOP_1_BIT);
usart_receiver_enable(USART2,TRUE);
nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
nvic_irq_enable(USART2_IRQn,0,0);
usart_interrupt_enable(USART2,USART_RDBF_INT,TRUE);
usart_enable(USART2,TRUE);
}
void parseGpsBuffer(void){
char *subString;
char *subStringNext;
int i = 0;
if(Save_Data.isGetData)
{
Save_Data.isGetData = FALSE;
printf("*****************\r\n");
printf("%s",Save_Data.GPS_Buffer);
for(i = 0; i <= 6; i++){
if(i == 0){
if((subString = strstr(Save_Data.GPS_Buffer, ",")) == NULL)
printf("解析错误");
}
else{
subString++;//到达解析数据中逗号的下一位
if((subStringNext = strstr(subString, ",")) != NULL)
{
char usefullBuffer[2];
switch(i){
case 1:
//利用subStringNext和subString的首地址相减来确定指针开辟空间的大小,以防指针不合法。
Save_Data.UTCTime = (char *)malloc((subStringNext - subString)*sizeof(char));
memcpy(Save_Data.UTCTime, subString, subStringNext - subString);
break;
case 2: memcpy(usefullBuffer, subString, subStringNext - subString); break; //定位状态,A=有效定位,V=无效定位
case 3: Save_Data.latitude = (char *)malloc((subStringNext - subString)*sizeof(char));
memcpy(Save_Data.latitude, subString, subStringNext - subString);
break;
case 4: Save_Data.N_S = (char *)malloc((subStringNext - subString)*sizeof(char));
memcpy(Save_Data.N_S, subString, subStringNext - subString);
break;
case 5: Save_Data.longitude = (char *)malloc((subStringNext - subString)*sizeof(char));
memcpy(Save_Data.longitude, subString, subStringNext - subString);
break;
case 6: Save_Data.E_W = (char *)malloc((subStringNext - subString)*sizeof(char));
memcpy(Save_Data.E_W, subString, subStringNext - subString);
break;
default: break;
}
subString = subStringNext;
Save_Data.isParseData = TRUE;
if(usefullBuffer[0] == 'A')
Save_Data.isUsefull = TRUE;
else if(usefullBuffer[0] == 'V')
Save_Data.isUsefull = FALSE;
}
else{
printf("解析错误2");
}
}
}
}
}
void printfGpsBuffer(void){
if(Save_Data.isParseData){
Save_Data.isParseData = FALSE;
printf("Save_Data.UTCTime = %s\r\n", Save_Data.UTCTime);//打印数据
free(Save_Data.UTCTime);//释放空间
if(Save_Data.isUsefull){
Save_Data.isUsefull = FALSE;
printf("Save_Data.latitude = %s\r\n", Save_Data.latitude);
free(Save_Data.latitude);
printf("Save_Data.N_S = %s\r\n", Save_Data.N_S);
free(Save_Data.N_S);
printf("Save_Data.longitude = %s\r\n", Save_Data.longitude);
free(Save_Data.longitude);
printf("Save_Data.E_W = %s\r\n", Save_Data.E_W);
free(Save_Data.E_W);
}
else
{
printf("GPS DATA is not usefull!\r\n");
}
}
}
/**
* @brief main function.
* @param none
* @retval none
*/
int main(void)
{
system_clock_config();
at32_board_init();
uart1_print_init(9600);
uart2_receive_init(9600);
while(1);
}
/**
* @brief this function handles usart2 handler.
* @param none
* @retval none
*/
void USART2_IRQHandler(void)
{
u8 res;
if(usart_flag_get(USART2,USART_RDBF_FLAG)!=RESET){
res = usart_data_receive(USART2);
if(res == '$'){
point1 = 0;
}
USAR2_RX_BUF[point1++] = res;
if(USAR2_RX_BUF[0] == '$' && USAR2_RX_BUF[4] == 'M' && USAR2_RX_BUF[5] == 'C'){
if(res == '\n'){
memcpy(Save_Data.GPS_Buffer, USAR2_RX_BUF, point1);
Save_Data.isGetData = TRUE;
point1 = 0;
memset(USAR2_RX_BUF, 0, USART2_MAX_RECV_LEN);
parseGpsBuffer();
printfGpsBuffer();
}
}
}
}
/**
**************************************************************************
* @file main.c
* @brief main program
*Read GPS information through seral port2 and prin out the information
*through serial port1
**************************************************************************
*/
#include "at32f403a_407_board.h"
#include "at32f403a_407_clock.h"
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "stdbool.h "
typedef struct Data
{
char RawData[200];
char UTCTime [50];
char Latitude [50];
char N_S [10];
char Longitude [50];
char E_W [10];
short int BufPoint;
}Data;
Data GPSdata;
/**
* @brief initialize uart1
* @param baudrate: uart baudrate
* @retval none
*/
void uart1_print_init(uint32_t baudrate)
{
gpio_init_type gpio_init_struct;
#if defined (__GNUC__) && !defined (__clang__)
setvbuf(stdout, NULL, _IONBF, 0);
#endif
/* enable the uart and gpio clock */
crm_periph_clock_enable(CRM_USART1_PERIPH_CLOCK, TRUE);
crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
gpio_default_para_init(&gpio_init_struct);
/* configure the uart tx pin */
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
gpio_init_struct.gpio_pins = GPIO_PINS_9;
gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
gpio_init(GPIOA, &gpio_init_struct);
/* configure uart param */
usart_init(USART1, baudrate, USART_DATA_8BITS, USART_STOP_1_BIT);
usart_transmitter_enable(USART1, TRUE);
usart_enable(USART1, TRUE);
}
/**
* @brief initialize uart2 RX:PA3 Read a row of GPS raw data
* @param baudrate: uart baudrate
* @retyal none
*/
void uart2_receive_init(uint32_t baudrate)
{
gpio_init_type gpio_init_struct;
/* enable the uart and gpio clock*/
crm_periph_clock_enable(CRM_USART2_PERIPH_CLOCK,TRUE);
crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK,TRUE);
gpio_default_para_init(&gpio_init_struct);
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
gpio_init_struct.gpio_mode = GPIO_MODE_INPUT;
gpio_init_struct.gpio_pins = GPIO_PINS_3;
gpio_init_struct.gpio_pull = GPIO_PULL_UP;
gpio_init(GPIOA,&gpio_init_struct);
usart_init(USART2,baudrate,USART_DATA_8BITS,USART_STOP_1_BIT);
usart_receiver_enable(USART2,TRUE);
nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
nvic_irq_enable(USART2_IRQn,0,0);
usart_interrupt_enable(USART2,USART_RDBF_INT,TRUE);
usart_enable(USART2,TRUE);
}
/**
* @brief parseGPSdata function
* @param nono
* @retval none
*/
/* eg. $GPGGA,082559.00,4005.22599,N,11632.58234,E,1,04,3.08,14.6,M,-5.6,M,,*76"*/
void parseGPSdata(void)
{
int h,m,s;
float flat,flon;
char tmp[10];
if(strstr(GPSdata.RawData,",,,,,")){
printf("Plase the GPS to open area \r\n");
return;
}
else{
sscanf(GPSdata.RawData,"%[^,],%[^,],%[^,],%[^,],%[^,],%[^,]",tmp,
GPSdata.UTCTime,GPSdata.Latitude,GPSdata.N_S,GPSdata.Longitude,GPSdata.E_W);
sscanf(GPSdata.Latitude+2,"%f",&flat);
flat = flat / 60;
flat += (GPSdata.Latitude[0]-'0')*10 + (GPSdata.Latitude[1]-'0');
sscanf(GPSdata.Longitude+3,"%f",&flon);
flon = flon / 60;
flon += (GPSdata.Longitude[0]-'0')*100 + (GPSdata.Longitude[1]-'0')*10 + (GPSdata.Longitude[2] - '0');
h = (GPSdata.UTCTime[0]-'0')*10 + (GPSdata.UTCTime[1]-'0') + 8;
m = (GPSdata.UTCTime[2]-'0')*10 + (GPSdata.UTCTime[3]-'0') ;
s = (GPSdata.UTCTime[4]-'0')*10 + (GPSdata.UTCTime[5]-'0') ;
printf("*****************************************\r\n");
printf("%s\r\n",GPSdata.RawData);
printf("Time:%d:%d:%d\r\n",h,m,s);
printf("Longitude:%.6f%s\r\n",flon,GPSdata.E_W);
printf("Latitude:%.6f%s\r\n",flat,GPSdata.N_S);
}
}
/**
* @brief main function.
* @param none
* @retval none
*/
int main(void)
{
system_clock_config();
at32_board_init();
uart1_print_init(9600);
uart2_receive_init(9600);
while(1);
}
/**
* @brief this function handles usart2 handler.
* @param none
* @retval none
*/
void USART2_IRQHandler(void)
{
char res;
if(usart_flag_get(USART2,USART_RDBF_FLAG)!=RESET)
{
res = usart_data_receive(USART2);
if(res == '$'){
GPSdata.BufPoint = 0;
}
GPSdata.RawData[GPSdata.BufPoint++] = res;
if( GPSdata.RawData[0] == '$' && GPSdata.RawData[4] == 'G' && GPSdata.RawData[5] == 'A'){
if(res == '\r' )
{
GPSdata.RawData[GPSdata.BufPoint] = '\0';
GPSdata.BufPoint = 0;
parseGPSdata();
}
}
}
}