本帖最后由 chinacn1989 于 2011-5-10 16:58 编辑
自己第一次写的东东,什么都不懂。问了很多。。。
终于编译通过,但是还没有仿真!
总觉得问题很多,就发来大家看看。多提点意见!
多指教指教!:handshake
注:笑脸为大写P,不知道怎么回事儿!
主要的构架:
定时器产生定时中断->AD,然后AD中断(数据处理)->显示
AD中断程序:
将数据采集起来,判断数据的值,是否为零点范围。如果是那么就为第一个点(i=0),记录零点值(ling=0),当ling能被2整除时(第一个零点也能被2整除),计算有效值。当不能被2整除时,ling++;不是零点范围,直接取值。
if(ling%2==0)
{
for(n=0;n<i;n++)
sn=sn+v[n]*v[n];
vm=sqrt(sn/n);
i=0; ling=0;
v=temp;
i++;
ling++;
}
else
v=temp;
i++;
ling++;
}
计算的是放在零点判断中,因为两个零点才是一个周期,当计算完成时,从第一个点重新开始,零点重新计数(i=0,ling=0)。
主要程序
#include"NUC1xx.h"
#include"stdio.h"
#include"math.h"
#include"display.c"
int i=0,ling=0; double temp,v[],vm;
void TMR0_IRQHandler(void) // 定时器中断子程序
{
GPIOA->;PMD.PMD2=0; //配置ADC5和ADC6为输入引脚,
GPIOA->;PMD.PMD3=0;
GPIOA->SCH|=0X00020000; //禁止IO数字输入通道
SYS->GPAMFP.ADC5=1;
SYS->GPAMFP.ADC6=1; //PA.5&PA.6作为AD输入
SYSCLK->CLKSEL1.ADC_S=2; //选择22M为ADC时钟频率
SYSCLK->CLKDIV.ADC_N=1; //ADC时钟源为:22/(ADC_N+1)=11MHz
SYSCLK->APBCLK.ADC_EN=1; //使能ADC时钟源
ADC->ADCR.ADEN=1; //使能adc模块
ADC->ADCR.DIFF=1; //采用差分输入模式
ADC->ADCR.ADMD=3; //通道采用连续扫描模式
ADC->ADCHER.CHEN=0X60; //选择ADC通道0和1
ADC->ADSR.ADF=1; //转换结束标志位清零
ADC->ADCR.ADIE=1; //开启AD中断使能
NVIC_EnableIRQ(ADC_IRQn); //使能AD中断
ADC->ADCR.ADST=1; //开始AD转换
}
void ADC_IRQHandler(void) // AD中断子程序
{
double m,sn=0;int n;
m=5*sin(1/128);
temp=ADC->ADDR[1].RSLT;
if(-m<temp && temp<m)
{
if(ling%2==0)
{
for(n=0;n<i;n++)
sn=sn+v[n]*v[n];
vm=sqrt(sn/n);
i=0; ling=0;
v=temp;
i++;
ling++;
}
else
v=temp;
i++;
ling++;
}
else
v=temp;
i++;
}
int main(void)
{
NVIC_DisableIRQ(TMR0_IRQn); //关闭TIME0中断
outpw(&TIMER0->TCSR ,0 ); //关闭 Timer0
/* Step 1. Enable and Select Timer clock source */
SYSCLK->CLKSEL1.TMR0_S = 4; //设置TIME0时钟频率为22MHz
SYSCLK->APBCLK.TMR0_EN =1; //使能时钟模块
/* Step 2. Select Operation mode */
TIMER0->TCSR.MODE=1; //设定定时器工作模式为周期溢出模式
/* Step 3. Select Time out period = (Period of timer clock input) * (8-bit Prescale + 1) * (24-bit TCMP)*/
TIMER0->TCSR.PRESCALE=0; // 不进行时钟预分频(设定值:0-255 )
TIMER0->TCMPR = 3456; // 溢出标志位设定,溢出周期计算
// (1/22118400)*(0+1)*(3456)= 156.25us / 6.4KHz=50Hz*128
/* Step 4. Enable interrupt */
TIMER0->TCSR.IE = 1; //使能time0定时器中断
TIMER0->TISR.TIF = 1; //定时器中断位清零
NVIC_EnableIRQ(TMR0_IRQn); //使能定时器中断
/* Step 5. Enable Timer module */
TIMER0->TCSR.CRST = 1; //计数器重置
TIMER0->TCSR.CEN = 1; //使能定时器
TIMER0->TCSR.TDR_EN=1; //使能time0数据寄存器
display(vm);
}
display.c
#include "nuc1xx.h"
#include "stdio.h"
#include "DrvGPIO.h"
#include "DrvSYS.h"
#define w GPIOA->DOUT
#define da GPIOB->DOUT
void delay(int i) //延时函数
{
int j,k;
for(j=0;j<i;j++)
for(k=0;k<255;j++);
}
void display(double x) //显示函数
{
unsigned char num[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //定义共阴极数码管字形编码0-9
unsigned char num1[]={0xbf,0x86,0xcb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef}; //定义共阴极数码管字型编码0.-9.
int a,b,c,d,e,m;
*((volatile unsigned int *)((uint32_t)&GPIOB->;PMD))= (*((volatile unsigned int *)((uint32_t)&GPIOB->;PMD))) | 0X5555; //定义PB0-PB7为输出端口
GPIOA->;PMD.PMD8=1; //PB8-11为输出端口
GPIOA->;PMD.PMD9=1;
GPIOA->;PMD.PMD10=1;
GPIOA->;PMD.PMD11=1;
GPIOB->SCH|=0X00000000; // 使能数字输入
SYS->GPAMFP.I2C0_SDA=0; //配置GPA8-11为IO口
SYS->GPAMFP.I2C0_SCL=0;
SYS->GPAMFP.I2C1_SDA=0;
SYS->GPAMFP.I2C1_SCL=0;
*((volatile unsigned int *)((uint32_t)&SYS->GPBMFP))= (*((volatile unsigned int *)((uint32_t)&SYS->GPBMFP))) & 0X00; //GPB为IO输出
m=1000*x; //将要显示的数据分离成单独的位
a=m/10000;
b=(m-a*10000)/1000;
c=(m-a*10000-b*1000)/100;
d=(m-a*10000-b*1000-c*100)/10;
e=m%10;
if(x<10)
while(1)
{
w|=0X0100; da=num[e]; delay(20);
w<<1; da=num[d]; delay(20);
w<<1; da=num[c]; delay(20);
w<<1; da=num1; delay(20);
}
else
while(1)
{
w|=0X0100; da=num[d]; delay(20);
w<<1; da=num[c]; delay(20);
w<<1; da=num; delay(20);
w<<1; da=num1[a]; delay(20);
}
}
附件为接口电路图! |