调试了好几天终于搞定ADC多路的数据采集,然后通过RS485传输到另一块ARM板上
上程序
/***********************************************************************
火牛开发板基础实验
串口实验
在串口1中输出实验标题,并打印串口1输入的字符
串口中断接收
************************************************************************/
#include "stm32f10x.h"
#include "string.h"
#include "stdio.h"
void Delay(unsigned short time);
/***********************************************************************
外设时钟使能
************************************************************************/
void RCC_Configuration(void)
{
/* 使能外设时钟 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 |
RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC |
RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_ADC1, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2 | RCC_APB1Periph_USART3, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
}
/*******************************************************************************
全部用到的引脚将在在配置
*******************************************************************************/
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* 配置串口1引脚 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure RS485 contrel pin: CTL */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* Configure RS485 pin: RX */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* Configure RS485 pin: TX */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
//PC5 作为模拟通道输入引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入引脚
GPIO_Init(GPIOC, &GPIO_InitStructure);
//PB0 作为模拟通道输入引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入引脚
GPIO_Init(GPIOB, &GPIO_InitStructure);
//PB1 作为模拟通道输入引脚
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入引脚
// GPIO_Init(GPIOB, &GPIO_InitStructure);
}
/*******************************************************************************
全部中断在此配置
*******************************************************************************/
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Configure the NVIC Preemption Priority Bits */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
/* Enable the USART1 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/*******************************************************************************
初始化时钟晶振 72MHZ
*******************************************************************************/
void SysClock_Init(void)
{
ErrorStatus HSEStartUpStatus;
RCC_DeInit();
RCC_HSEConfig(RCC_HSE_ON);
HSEStartUpStatus = RCC_WaitForHSEStartUp();
if(HSEStartUpStatus == SUCCESS){
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
FLASH_SetLatency(FLASH_Latency_2);
RCC_HCLKConfig(RCC_SYSCLK_Div1);
RCC_PCLK2Config(RCC_HCLK_Div1);
RCC_PCLK1Config(RCC_HCLK_Div2);
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
RCC_PLLCmd(ENABLE);
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET){
;
}
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
while(RCC_GetSYSCLKSource() != 0x08){
;
}
}
}
/*****************************************************************
USART1 初始化 baud 波特率
*****************************************************************/
void USART1_Init(unsigned int baud)
{
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = baud;
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(USART1, &USART_InitStructure);
//USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
USART_Cmd(USART1, ENABLE);
}
void RS485_Init(void)
{
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 115200;
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(USART3, &USART_InitStructure);
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
USART_Cmd(USART3, ENABLE);
}
void RS485_SendByte(unsigned char temp)
{
// while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
GPIO_SetBits(GPIOB, GPIO_Pin_2);
Delay(100);
USART_SendData(USART3, temp);
while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
Delay(100);
GPIO_ResetBits(GPIOB, GPIO_Pin_2);
//return(temp);
}
unsigned char RS485_GetByte(void)
{
while(USART_GetFlagStatus(USART3, USART_FLAG_RXNE) == RESET);
return(USART_ReceiveData(USART3)); //?????
}
void RS485_SendString (char *s)
{
while (*s != '/0')
{
RS485_SendByte(*(unsigned char *)s);
s++;
}
}
/*****************************************************************
从 USART1 发送一个字节
*****************************************************************/
void USART1_SendByte(unsigned char temp)
{
USART_SendData(USART1, temp);
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}
void USART1_GetByte(void)
{
while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);
USART_ReceiveData(USART1);
}
/*****************************************************************
从 USART1 发送字符串
*****************************************************************/
void USART1_Printf(char *pch)
{
while(*pch != '/0'){
USART1_SendByte(*(unsigned char *)pch);
pch++;
}
}
/******************************************
*
* 延时程序 ms
*
****************************************/
void Delay(unsigned short time)
{
unsigned short i, j;
for(; time > 0; time--){
for(j = 0; j < 10; j++){
for(i = 0; i < 1000; i++);
}
}
}
#define ADC1_DR_Address ((u32)0x4001244C)
vu16 ADCConvertedValue;
void ADC_Configuration(void)
{
DMA_InitTypeDef DMA_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
DMA_DeInit(DMA1_Channel1); // ?
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADCConvertedValue;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = 2;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//DMA_MemoryInc_Disable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
/* Enable DMA1 channel1 */
DMA_Cmd(DMA1_Channel1, ENABLE);
/* ADC1 configuration ------------------------------------------------------*/
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = ENABLE; // ENABLE
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 2;
ADC_InitStructure.ADC_Interrupt_EOCIE = 0; //no interrupt
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 regular channel14 configuration ADC_Channel_15*/
ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_55Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_15, 2, ADC_SampleTime_55Cycles5);
/* Enable ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE);
/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);
/* Enable ADC1 reset calibaration register */
ADC_ResetCalibration(ADC1);
/* Check the end of ADC1 reset calibration register */
while(ADC_GetResetCalibrationStatus(ADC1));
/* Start ADC1 calibaration */
ADC_StartCalibration(ADC1);
/* Check the end of ADC1 calibration */
while(ADC_GetCalibrationStatus(ADC1));
/* Start ADC1 Software Conversion */
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
/*******************************************************
MAIN 函数
*******************************************************/
int main(void)
{
char string[50] = "";
SysClock_Init(); // 初始化系统时钟 72MHZ
RCC_Configuration(); // 使能外设
GPIO_Configuration(); // 配置引脚
GPIO_ResetBits(GPIOB, GPIO_Pin_2);
NVIC_Configuration(); // 配置中断
USART1_Init(115200); // 配置串口1,波特率9600
RS485_Init();
ADC_Configuration();
USART1_Printf("火牛开发板基础实验");
while(1){
while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC));
sprintf(string, "ADC8 Value:%dmV/r/n", (ADCConvertedValue*3300/4096));
RS485_SendString(string);
sprintf(string, "ADC15 Value:%dmV/r/n", ((*(&ADCConvertedValue+1))*3300/4096));
RS485_SendString(string);
ADC_ClearFlag(ADC1,ADC_FLAG_EOC);
}
}
说明:
本例规则通道里面含有2路ADC,EOC转换完成意思是说规则通道转换完毕才置位,就是两路ADC都转换完了才置位,DMA把转换完成的采样数据送到指定SRAM里面,然后再从SRAM中读出来,就是采样得到的数据。