高级会员
 
主题
帖子
积分2691
阅读权限30
注册时间2012-10-23
最后登录1970-1-1
在线时间 小时
|

楼主 |
发表于 2012-12-7 22:47
|
显示全部楼层
仿STC的LCR程序,用PWM生成正弦波。
stm32频率高,且PWM分辨力也高,生成正弦波的质量比原来的好很多。
/************************
实验目标:
生成正弦波
*************************/
#include "stm32f10x.h"
#include "math.h"
//================================================================
//========================常用函数================================
//================================================================
void delay(u32 n){ u32 i; for(i=0;i<n;i++); } //延时
void PAinit(u16 n,GPIOMode_TypeDef mo){//PA端口设置
//GPIO_Mode_IPU 上拉输入
//GPIO_Mode_IPD 下拉输入
//GPIO_Mode_Out_PP 推挽输出
GPIO_InitTypeDef g;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //PA钟源
g.GPIO_Speed = GPIO_Speed_50MHz; //端口速度
g.GPIO_Mode = mo; //端口模式
g.GPIO_Pin = n; //脚位
GPIO_Init(GPIOA, &g);
}
void PBinit(u16 n,GPIOMode_TypeDef mo){//PB端口设置
GPIO_InitTypeDef g;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //PB钟源
g.GPIO_Speed = GPIO_Speed_50MHz; //端口速度
g.GPIO_Mode = mo; //端口模式
g.GPIO_Pin = n; //脚位
GPIO_Init(GPIOB, &g);
}
//================================================================
//=========================dds函数================================
//================================================================
u16 DDSbuf[2400] = {0};
void DDS_cnf(int f) //f=DDS输出频率
{
//DDS时钟=72MHz/m,输出频率=72MHz/m/n
u16 m = 1000,n =3,i;
if(f==10000) m=40, n=180; //分频参数
if(f==1000) m=200,n=360; //分频参数
if(f==100) m=300,n=2400; //分频参数
for(i=0;i<n;i++) //创建DDS查询表
DDSbuf[i] = (sin(2*3.1415926535*i/n)+1)*(m-2)/2+1.5;
{//端口及钟源设置
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //DMA钟源
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //TIM3钟源
PAinit(GPIO_Pin_6, GPIO_Mode_AF_PP); //TM3 CH1脚位是PA6,置为复用推挽输出
}
{//DMA设置,详见函数库手册第90页解释
DMA_InitTypeDef D;
DMA_DeInit(DMA1_Channel3); //DMA1_3通道初始化
D.DMA_PeripheralBaseAddr = 0x40000434; //DMA外设基址 TIM3_CCR1_Address
D.DMA_MemoryBaseAddr = (u32)DDSbuf; //DMA内存基址
D.DMA_DIR = DMA_DIR_PeripheralDST; //DST:外设作为数据传送目的地址,SRC:外设作为传送源地址
D.DMA_BufferSize = n; //DMA缓存大小
D.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器不自增
D.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址寄存器自增
D.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //外存字宽16bit
D.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //内存字宽16bit
D.DMA_Mode = DMA_Mode_Circular; //工作在循环模式
D.DMA_Priority = DMA_Priority_High; //DMA置为高优先级
D.DMA_M2M = DMA_M2M_Disable; //不置为内存到内存传输
DMA_Init(DMA1_Channel3, &D); //初始化DMA1
DMA_Cmd(DMA1_Channel3, ENABLE); //DMA1_3使能
}
{//定时器设置
TIM_TimeBaseInitTypeDef tm;
TIM_OCInitTypeDef tc;
tm.TIM_Period = m-1; //当定时器从0计数到m-1,即为m次,为一个定时周期
tm.TIM_Prescaler = 0; //设置预分频:不预分频,即为36MHz
tm.TIM_ClockDivision = 0; //设置时钟分频系数:不分频
tm.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseInit(TIM3, &tm); //初始化TIM3
//PWM通道1模式设置
tc.TIM_OCMode = TIM_OCMode_PWM1; //配置为PWM模式1
tc.TIM_OutputState = TIM_OutputState_Enable;
tc.TIM_Pulse = DDSbuf[0]; //设置跳变值,当计数器计数到这个值时,电平发生跳变
tc.TIM_OCPolarity = TIM_OCPolarity_High; //当定时器计数值小于CCR1_Val时为高电平
TIM_OC1Init(TIM3, &tc); //初始化TIM3的通道1
TIM_DMACmd(TIM3, TIM_DMA_Update, ENABLE); //TIM3 DMA请求使能,注:TIM3_Update请求对应DMA1_chanel3通道
TIM_Cmd(TIM3, ENABLE); //TIM3使能
}
}
int main(void)
{
u8 kn=0,bk=0;
SystemInit(); //配置系统时钟为72MHz
PAinit(GPIO_Pin_0, GPIO_Mode_IPU); //PA0置为上拉输入
DDS_cnf(100); //设置DDS输出
while (1){
if((GPIOA->IDR&1)==0) { if(kn<255) kn++; }
else kn=0;
if(kn==3){
bk=(bk+1)%3;
if(bk==0) DDS_cnf(100);
if(bk==1) DDS_cnf(1000);
if(bk==2) DDS_cnf(10000);
}
delay(10000);
}
} |
|