与生成三角波相关的寄存器如下
MAMP1[3:0]是用来设置通道1三角波的幅值的,如果设置为4096,那么产生的三角波就是0-3.3伏的,如果改为2047,那么产生的就是0-1.65伏的三角波,我一开始以为这个寄存器更改的只是三角波产生的精度,后来使用示波器测量后发现并不是这样。
WAVE1[1:0]是用来设置通道1产生的波形的,可以设置为噪声波、三角波以及不生成。
TSEL1[2:0]是用来设置通道1触发器的选择,可以使用定时器TRGO时间触发,也可以使用外部中断以及软件触发的方式,但后俩者我并没有尝试。
TEN1是通道1触发使能,*注意*这个必须首先置1否则波形设置以及触发器设置都是无法进行的。
//DAC通道1输出初始化 void Dac1_Init(void) { RCC->APB1ENR|=1<<29; //使能DAC时钟 RCC->AHB1ENR|=1<<0; //使能PORTA时钟 GPIO_Set(GPIOA,PIN4,GPIO_MODE_AIN,0,0,GPIO_PUPD_PU);//PA4,模拟输入,下拉 DAC->CR|=1<<2; //使能触发功能 TEN1=1 DAC->CR|=1<<1; //DAC1输出缓存不使能 BOFF1=1 DAC->CR|=4<<3; //DAC TIM2 TRGO,不过要TEN1=1才行 DAC->CR|=2<<6; //生成三角波 DAC->CR|=12<<8; //设置振幅4095 DAC->CR|=0<<12; //DAC1 DMA不使能 DAC->CR|=1<<0; //使能DAC1 DAC->DHR12R1=0; }
//TIM2初始化 //arr:自动重装载值 psc:预分频系数 void TIM2_Int_Init(u16 arr,u16 psc) { RCC->APB1ENR|=1<<0; //TIM2时钟使能 TIM2->ARR=arr; //设定计数器自动重装值 TIM2->PSC=psc; //预分频器 TIM2->CR2|=2<<4; //选择更新事件作为触发输出(TRGO) TIM2->CR1|=0x01; //使能定时器2 }
主函数只需要调用这俩个初始化函数,在三个APB1周期后在PA4就会产生三角波。
二、接下来是介绍如何产生正弦波
寄存器配置
TSEL1[2:0]、TEN1也是必须配置的,此外还需要配置
/*DAC1通道2初始化*/ RCC->APB1ENR|=1<<29; //使能DAC时钟 RCC->AHB1ENR|=1<<0; //使能PORTA时钟 GPIO_Set(GPIOA,PIN5,GPIO_MODE_AIN,0,0,GPIO_PUPD_PU);//PA5,模拟输入,下拉 DAC->CR|=1<<18; //使能触发功能 TEN1=1 DAC->CR|=1<<17; //DAC1输出缓存不使能 BOFF1=1 DAC->CR|=5<<19; //DAC TIM4 TRGO,不过要TEN1=1才行 DAC->CR|=0<<22; //禁止生成波形 DAC->CR|=1<<28; //DAC1 通道2 DMA使能 DAC->CR|=1<<16; //使能DAC1 通道2 DAC->DHR12R2=0;
const u16 Sine12bit2[500] = { 2048,2073,2099,2125,2150,2176,2202,2227,2253,2279,2304,2330,2355,2380, 2406,2431,2456,2482,2507,2532,2557,2582,2606,2631,2656,2680,2705,2729,2753, 2777,2801,2825,2849,2872,2896,2919,2942,2966,2988,3011,3034,3056,3079,3101, 3123,3145,3166,3188,3209,3230,3251,3272,3292,3313,3333,3353,3372,3392,3411, 3430,3449,3468,3486,3504,3522,3540,3558,3575,3592,3609,3625,3641,3657,3673, 3689,3704,3719,3734,3748,3762,3776,3790,3803,3816,3829,3842,3854,3866,3878, 3889,3900,3911,3921,3932,3942,3951,3961,3970,3978,3987,3995,4003,4010,4017, 4024,4031,4037,4043,4048,4054,4059,4063,4068,4072,4075,4079,4082,4085,4087, 4089,4091,4092,4094,4094,4095,4095,4095,4094,4094,4092,4091,4089,4087,4085, 4082,4079,4075,4072,4068,4063,4059,4054,4048,4043,4037,4031,4024,4017,4010, 4003,3995,3987,3978,3970,3961,3951,3942,3932,3921,3911,3900,3889,3878,3866, 3854,3842,3829,3816,3803,3790,3776,3762,3748,3734,3719,3704,3689,3673,3657, 3641,3625,3609,3592,3575,3558,3540,3522,3504,3486,3468,3449,3430,3411,3392, 3372,3353,3333,3313,3292,3272,3251,3230,3209,3188,3166,3145,3123,3101,3079, 3056,3034,3011,2988,2966,2943,2919,2896,2872,2849,2825,2801,2777,2753,2729, 2705,2680,2656,2631,2606,2582,2557,2532,2507,2482,2456,2431,2406,2381,2355, 2330,2304,2279,2253,2227,2202,2176,2150,2125,2099,2073,2048,2022,1996,1970, 1945,1919,1893,1868,1842,1816,1791,1765,1740,1715,1689,1664,1639,1613,1588, 1563,1538,1513,1489,1464,1439,1415,1390,1366,1342,1318,1294,1270,1246,1223, 1199,1176,1153,1129,1107,1084,1061,1039,1016,994,972,950,929,907,886,865, 844,823,803,782,762,742,723,703,684,665,646,627,609,591,573,555,537,520, 503,486,470,454,438,422,406,391,376,361,347,333,319,305,292,279,266,253, 241,229,217,206,195,184,174,163,153,144,134,125,117,108,100,92,85,78,71, 64,58,52,47,41,36,32,27,23,20,16,13,10,8,6,4,3,1,1,0,0,0,1,1,3,4,6,8,10, 13,16,20,23,27,32,36,41,47,52,58,64,71,78,85,92,100,108,117,125,134,144, 153,163,174,184,195,206,217,229,241,253,266,279,292,305,319,333,347,361, 376,391,406,422,438,454,470,486,503,520,537,555,573,591,609,627,646,665, 684,703,723,742,762,782,803,823,844,865,886,907,929,950,972,994,1016,1039, 1061,1084,1107,1129,1153,1176,1199,1223,1246,1270,1294,1318,1342,1366,1390, 1415,1439,1464,1489,1513,1538,1563,1588,1613,1639,1664,1689,1715,1740,1765, 1791,1816,1842,1868,1893,1919,1945,1970,1996,2022}; u16 DualSine12bit[500];
u32 Idx; /*读入正弦波数据*/ for (Idx = 0; Idx < 500; Idx++) { DualSine12bit[Idx] = (Sine12bit2[Idx] << 16) + (Sine12bit2[Idx]); }
配置代码如下:
//初始化DMA通道 void SinWave_DMA_Config() { RCC->AHB1ENR|=1<<21;//DMA1时钟使能 DMA1_Stream6->PAR=(u32)&(DAC->DHR12R2); //DMA外设地址 DMA1_Stream6->M0AR=(u32)DualSine12bit; //DMA 存储器0地址 DMA1_Stream6->NDTR=500; //传输500个数据 DMA1_Stream6->CR=0; //先全部复位CR寄存器值 DMA1_Stream6->CR|=1<<6; //存储器到外设模式 DMA1_Stream6->CR|=1<<8; //循环模式 DMA1_Stream6->CR|=0<<9; //外设非增量模式 DMA1_Stream6->CR|=1<<10; //存储器增量模式 DMA1_Stream6->CR|=1<<11; //外设数据长度:16位 DMA1_Stream6->CR|=1<<13; //存储器数据长度:16位 DMA1_Stream6->CR|=1<<16; //中等优先级 DMA1_Stream6->CR|=0<<21; //外设突发单次传输 DMA1_Stream6->CR|=0<<23; //存储器突发单次传输 DMA1_Stream6->CR|=(u32)7<<25;//通道选择(5通道) }
//初始化TIM4 void SinWave_TIM_Config(u16 arr,u16 psc) { RCC->APB1ENR|=1<<2; //TIM2时钟使能 TIM4->ARR=arr; //设定计数器自动重装值 TIM4->PSC=psc; //预分频器 TIM4->CR2|=2<<4; //选择更新事件作为触发输出(TRGO) TIM4->CR1|=0x01; //使能定时器4 }
最后使能DMA传输,所有的配置就完成了。
三、总结
文章来源: 使用stm32产生三角波和正弦波