网上找到一个例程,注释了一下,不知道对不对,尤其是有红色的部分,语法难以理解,主要是没弄明白右移的作用是什么。原子哥,帮帮忙吧!
#include "Print.h"
u16 Regular[64]={0}, Injected[32]={0};
u8 tmp=64,j=0;
int main()
{
UsartInit(9600);
//RCC
RCC->CFGR = RCC->CFGR & ~(3<<14) | (1<<14);//PCLK2 4分频后作为ADC时钟
RCC->AHBENR |= 0x01;//DMA1时钟开启。
RCC->APB2ENR |= 0x0295;//使能PA、PC、PF、ADC1时钟、辅助功能IO时钟
AFIO->MAPR = AFIO->MAPR & ~(7<<24) | 4<<24;//关闭JTAG-DP,关闭SW-DP
//NVIC
/*SCB->AIRCR的修改需要通过在高16位写入0X05FA这个密钥才能修改的,
故在设置AIRCR之前,应该把密钥加入到要写入的内容的高16位,以保证能
正常的写入AIRCR。抢占优先级和子优先级各占几个位又要根据SCB->AIRCR
中中断分组的设置来决定,这里是组1,每个中断的中断优先寄存器的高四位
中的最高1位是抢占优先级,低3位是响应优先级。*/
SCB->AIRCR = SCB->AIRCR & 0x0000F8FF | 0x05FA0600;//写入密钥并设置中断分组为组1
NVIC->IPR[ADC1_2_IRQn] = 0x00;//ADC1和2的抢占和响应中断优先级均设置为0
NVIC->ISER[ADC1_2_IRQn>>5] = 1<<(ADC1_2_IRQn&0x1F);//NVIC->ISER[0]中的ADC1和ADC2的全局中断使能位置1
SysTick->CTRL = 0x00;
//GPIO
GPIOA->CRL &= 0xFFF0FFFF;//PA4模拟输入
GPIOF->CRH = GPIOF->CRH & 0x0FFF0FFF | 0x80008000;//PF11、PF15设置为上下拉输入
GPIOF->BSRR = 1 << 11 | 1<<15;//设置PF11、PF15对应的ODR位为1
GPIOC->CRL &= 0xFFF0F00F;//PC1、PC2、PC4模拟输入
//EXTI
/* 选择PF11作为EXTI11作为外部中断输入源 */
AFIO->EXTICR[11>>2] = AFIO->EXTICR[11>>2] & ~AFIO_EXTICR3_EXTI11 | AFIO_EXTICR3_EXTI11_PF;//改为AFIO_EXTICR3_EXTI11_Px
EXTI->IMR = EXTI->IMR & ~(1<<11) | 0<<11;//关闭line 11上的中断
EXTI->EMR = EXTI->EMR & ~(1<<11) | 1<<11;//开放来自line 11上的事件请求
EXTI->RTSR = EXTI->RTSR & ~(1<<11) | 0<<11;//line 11上事件上升降沿不触发
EXTI->FTSR = EXTI->FTSR & ~(1<<11) | 1<<11;//line 11上事件下降沿触发
AFIO->EXTICR[15>>2] = AFIO->EXTICR[15>>2] & ~AFIO_EXTICR4_EXTI15 | AFIO_EXTICR4_EXTI15_PF;//改为AFIO_EXTICR4_EXTI15_Px
EXTI->IMR = EXTI->IMR & ~(1<<15) | 0<<15;
EXTI->EMR = EXTI->EMR & ~(1<<15) | 1<<15;
EXTI->RTSR = EXTI->RTSR & ~(1<<15) | 0<<15;
EXTI->FTSR = EXTI->FTSR & ~(1<<15) | 1<<15;
//DMA
DMA1_Channel1->CCR = 0x25A0;//循环模式
//从外设读
//外设地址非增量模式
//存储器增量模式
//外设数据宽度为16位
//存储器数据宽度16位
//中等优先级
//非存储器到存储器模式
DMA1_Channel1->CNDTR = 64;//DMA1,传输数据量64字节
DMA1_Channel1->CPAR = 0x4001244C;//DMA1 外设地址为ADC_DR寄存器
DMA1_Channel1->CMAR = (u32)Regular;//DMA1,存储器地址
DMA1_Channel1->CCR |= 0x01;//开启DMA传输
//ADC1
ADC1->CR1 = ADC1->CR1 & 0xFFF0065F | 0<<5 | 1<<7 | 1<<8 | 1<<11 | 0<<13;//禁止EOC中断,允许JEOC中断,使用扫描模式,规则通道组上使用间断模式,收到外部触发后转换规则通道的数目为1个
ADC1->CR2 = ADC1->CR2 & 0xFF8106F0 | 0x001CE100;//单次转换模式;校准完成;校准寄存器已初始化;使用DMA模式,右对齐,注入通道组转换EXTI线15/TIM8_CC4事件触发,注入通道使用外部触发转换模式,规则通道组转换的外部事件为EXTI线11/ TIM8_TRGO事件,使用规则通道外部触发转换模式
ADC1->SMPR1 = ADC1->SMPR1 & ~(7<<3) | 3<<3;//选择通道11的采样时间为28.5周期
ADC1->SMPR1 = ADC1->SMPR1 & ~(7<<6) | 3<<6;//选择通道12的采样时间为28.5周期
ADC1->SMPR1 = ADC1->SMPR1 & ~(7<<12) | 3<<12;//选择通道14的采样时间为28.5周期
ADC1->SMPR2 = ADC1->SMPR2 & ~(7<<12) | 3<<12;//选择通道4的采样时间为28.5周期
ADC1->SQR1 = ADC1->SQR1 & ~(0x0F<<20) | 1<<20;//规则通道序列长度为2个转换
ADC1->SQR3 = ADC1->SQR3 & ~(0x1F<<0) | 0x04<<0;//规则序列中的第1个转换是通道4
ADC1->SQR3 = ADC1->SQR3 & ~(0x1F<<5) | 0x0E<<5;//规则序列中的第2个转换是通道14
ADC1->JSQR = ADC1->JSQR & ~(3<<20) | 1<<20;//注入通道序列长度为2个转换
ADC1->JSQR = ADC1->JSQR & ~(0x1F<<10) | 0x0B<<10;//注入序列中的第3个转换是通道11
ADC1->JSQR = ADC1->JSQR & ~(0x1F<<15) | 0x0C<<15;//注入序列中的第2个转换是通道12
ADC1->CR2 |= 0x09;//开启ADC并启动转换,初始化校准寄存器。
while(ADC1->CR2 & 0x08);//等待校准结束
ADC1->CR2 |= 0x04;//开启AD校准
while(ADC1->CR2 & 0x04);//等待校准结束
while(1)
{
for(j=64-tmp,tmp=DMA1_Channel1->CNDTR;j+tmp<65?j<64-tmp:j<128-tmp;j++)
printf("Regular[%d] = %d\r\n",j%64, Regular[j%64]);
}
}
|