[mw_shl_code=c,true]主函数:
#include "stm32f10x_lib.h"
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "adc.h"
#include "dma.h"
// #define USART3_DR_Base 0x40004804
//#define ADC1_DR_Address 0x4001244C //0x40012400+0x4C
void Uart3_PutChar(u8 ch);
void Uart3_PutString(u8 *Buf, u8 Len);
int main(void)
{
float temp=0;
u16 t;
u32 temp1 =0;
u32 adcx,adcx1,adcx2;
u8 table[6];
u8 *p;
p= table;
Stm32_Clock_Init(9);//88M
delay_init(72); //延时初始化
uart_init(72,9600);
Adc_Init();
MYDMA_Config(DMA1_Channel1,(u32) &ADC1->DR);//配置DMA通道1
ADC1->CR2|=1<<8; //开启ADC DMA转换
MYDMA_Enable(DMA1_Channel1);//开启DMA通道1
ADC1->CR2|=1<<0; //开启AD转换
while (1)
{
// if(DMA1->ISR&(1<<1)) //传输完成了
// {
adcx=ADC_Buf[0];
adcx1=ADC_Buf[1];
adcx2=ADC_Buf[2];
temp=(float)adcx*(3.3/4096);
adcx=temp;
temp-=adcx;
temp*=1000;
table[0]=adcx+0x30;
table[1]='.';
table[2]=(int)temp / 100 + 0x30;
table[3]=(int)temp % 100/10 + 0x30;
table[4]=(int)temp %10 + 0x30;
table[5]='V';
printf("CH10 DATA:");
printf("CH10 DATA:");
Uart3_PutString(p,6);
temp=(float)adcx1*(3.3/4096);
adcx1=temp;
temp-=adcx1;
temp*=1000;
table[0]=adcx1+0x30;
table[1]='.';
table[2]=(int)temp / 100 + 0x30;
table[3]=(int)temp % 100/10 + 0x30;
table[4]=(int)temp %10 + 0x30;
table[5]='V';
printf("CH8 DATA:");
Uart3_PutString(p,6);
temp=(float)adcx2*(3.3/4096);
adcx2=temp;
temp-=adcx2;
temp*=1000;
table[0]=adcx2+0x30;
table[1]='.';
table[2]=(int)temp / 100 + 0x30;
table[3]=(int)temp % 100/10 + 0x30;
table[4]=(int)temp %10 + 0x30;
table[5]='V';
printf("CH9 DATA:");
Uart3_PutString(p,6);
Uart3_PutString("\r\n",2);
// DMA1->IFCR|=1<<1;
delay_ms(1000);
// MYDMA_Enable(DMA1_Channel1);
// }
}
}
void Uart3_PutChar(u8 ch)
{
USART3->DR = (u8) ch;
while((USART3->SR&0X40)==0);//循环发送,直到发送完毕
}
void Uart3_PutString(u8 *Buf, u8 Len)
{
u8 i;
for(i= 0; i<Len; i++)
{
Uart3_PutChar(*Buf++);
}
}
usart函数:
#include "sys.h"
#include "usart.h"
#if 1
#pragma import(__use_no_semihosting)
//标准库需要的支持函数
struct __FILE
{
int handle;
/* Whatever you require here. If the only file you are using is */
/* standard output using printf() for debugging, no file handling */
/* is required. */
};
/* FILE is typedef’ d in stdio.h. */
FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
_sys_exit(int x)
{
x = x;
}
//重定义fputc函数
int fputc(int ch, FILE *f)
{
while((USART3->SR&0X40)==0);//循环发送,直到发送完毕
USART3->DR = (u8) ch;
return ch;
}
#endif
//end
//////////////////////////////////////////////////////////////////
#ifdef EN_USART3_RX //如果使能了接收
//串口3中断服务程序
//注意,读取USARTx->SR能避免莫名其妙的错误
u8 USART_RX_BUF[64]; //接收缓冲,最大64个字节.
//接收状态
//bit7,接收完成标志
//bit6,接收到0x0d
//bit5~0,接收到的有效字节数目
u8 USART_RX_STA=0; //接收状态标记
void USART3_IRQHandler(void)
{
u8 res;
if(USART3->SR&(1<<5))//接收到数据
{
res=USART3->DR;
if((USART_RX_STA&0x80)==0)//接收未完成
{
if(USART_RX_STA&0x40)//接收到了0x0d
{
if(res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
else USART_RX_STA|=0x80; //接收完成了
}else //还没收到0X0D
{
if(res==0x0d)USART_RX_STA|=0x40;
else
{
USART_RX_BUF[USART_RX_STA&0X3F]=res;
USART_RX_STA++;
if(USART_RX_STA>63)USART_RX_STA=0;//接收数据错误,重新开始接收
}
}
}
}
}
#endif
//初始化IO 串口3
//pclk2  CLK2时钟频率(Mhz)
//bound:波特率
//CHECK OK
//091209
void uart_init(u32 pclk2,u32 bound)
{
float temp;
u16 mantissa;
u16 fraction;
temp=(float)(pclk2*1000000)/(bound*16);//得到USARTDIV
mantissa=temp; //得到整数部分
fraction=(temp-mantissa)*16; //得到小数部分
mantissa<<=4;
mantissa+=fraction;
RCC->APB2ENR|=1<<3; //使能PORTB口时钟
RCC->APB2ENR|=1<<18; //使能串口时钟
GPIOC->CRH&=0XFFFF00FF;
GPIOC->CRH|=0X00008B00;//IO状态设置
RCC->APB2RSTR|=1<<18; //复位串口3
RCC->APB2RSTR&=~(1<<18);//停止复位
//波特率设置
USART3->BRR=mantissa; // 波特率设置
USART3->CR1|=0X200C; //1位停止,无校验位.
#ifdef EN_USART3_RX //如果使能了接收
//使能接收中断
USART3->CR1|=1<<8; //PE中断使能
USART3->CR1|=1<<5; //接收缓冲区非空中断使能
MY_NVIC_Init(3,3,USART3_IRQChannel,2);//组2,最低优先级
#endif
}
adc函数:
#include <stm32f10x_lib.h>
#include "adc.h"
void Adc_Init(void)
{
RCC->APB2ENR|=1<<4; //使能PORTc口时钟
RCC->APB2ENR|=1<<3; //使能PORTB08口时钟
GPIOC->CRL&=0XFFFFFFF0;//Pc.0 anolog输入
GPIOB->CRL&=0XFFFFFF00;//PB0、PB1 ADC8 ADC9 anolog输入
RCC->APB2ENR|=1<<9; //ADC1时钟使能
__nop();
__nop();
RCC->APB2RSTR|=1<<9; //ADC1复位
RCC->APB2RSTR&=~(1<<9);//复位结束
RCC->CFGR|=3<<14; //SYSCLK/DIV2=88M/8=11Mhz 得到ADC采样率位43.65Khz
ADC1->CR1&=0XF0FFFF; //独立工作模式
ADC1->CR1|=1<<8; //扫描模式
ADC1->CR2|=1<<1; //连续转换模式
ADC1->CR2|=0x000E0000; //软件控制转换 由bit21控制
ADC1->CR2|=1<<20; //使用用外部触发(SWSTART)!!! 必须使用一个事件来触发
ADC1->CR2&=~(1<<11); //右对齐
ADC1->SQR1&=~(0XF<<20);
ADC1->SQR1|=1<<21; //3个转换在规则序列中
// ADC1->SQR3&=0XFFFFFFE0;//规则序列1=通道0
// ADC1->SQR3|=10;
ADC1->SQR3&=0XFFFF8000;//规则序列 通道ch
ADC1->SQR3|=0X0000A50A; //10 8 9
ADC1->SMPR1&=0XFFFFFFF8; //通道10的转换时间为:239.5+12.5个ADC时钟周期
ADC1->SMPR1|=7<<0; //通道0 239.5周期,提高采样时间可以提高精确度
ADC1->SMPR2&=0X00FFFFFF; //通道89的转换时间为:239.5+12.5个ADC时钟周期
ADC1->SMPR2|=0xFFFFFFFF; //通道89 239.5周期,提高采样时间可以提高精确度
ADC1->CR2|=1<<0; //开启AD转换器,第一次唤醒AD转换器
ADC1->CR2|=1<<3; //使能复位校准
while(ADC1->CR2&1<<3); //等待校准结束
//该位由软件设置并由硬件清除。在校准寄存器被初始化后该位将被清除。
ADC1->CR2|=1<<2; //开启AD校准
while(ADC1->CR2&1<<2); //等待校准结束
//该位由软件设置以开始校准,并在校准结束时由硬件清除
}
//获得ADC值
//ch:通道值 0~3
u16 Get_Adc(u8 ch)
{
//设置转换序列
ADC1->SQR3&=0XFFFFFC00;//规则序列1 通道ch
ADC1->SQR3|=0X0000A50A; //10 8 9
ADC1->CR2|=1<<22; //启动规则转换通道
while(!(ADC1->SR&1<<1));//等待转换结束
return ADC1->DR; //返回adc值
}[/mw_shl_code]
之前串口助手是可以显示出来3.3V电压,但不能收到的发送数据,后来改了下串口设置,就可以收到发送数据,但却采集不到3.3V的3路电压。。。请问哪里需要改下呢?? |