S3C2440裸机实现超声波测距(US100模块)

来源:互联网 发布:股票数据网站 编辑:程序博客网 时间:2024/06/02 08:52

1.main.c文件如下

/**************************************************************** 文件名: Ultrasonic.c 作者:小炼子 编写时间:2014.06.28 功能:超声波测距,TQ2440接US100超声波测距模块,测量结果串口打印出来,单位mm 计算方法:采用初略计算,距离=时间*速度/2 编写原因:验证US100超声波测距模块在TQ2440板上的可行性 ****************************************************************/#defineGLOBAL_CLK1#include <stdlib.h>#include <string.h>#include "def.h"#include "option.h"#include "2440addr.h"#include "2440lib.h"#include "2440slib.h"#include "mcx314.h"#include "mmu.h"#include "timer.h"extern char Image$$ER_ROM1$$RO$$Limit[]; extern char Image$$ER_ROM1$$RO$$Base[]; extern char Image$$RW_RAM1$$RW$$Limit[]; extern char Image$$RW_RAM1$$RW$$Base[]; extern char Image$$RW_RAM1$$ZI$$Limit[]; extern char Image$$RW_RAM1$$ZI$$Base[]; void Isr_Init(void);void HaltUndef(void);void HaltSwi(void);void HaltPabort(void);void HaltDabort(void);void ClearMemory(void);void Init_Ultrasonic(void);void delay10us(void);void Clk0_Enable(int clock_sel);void Clk1_Enable(int clock_sel);void Clk0_Disable(void);void Clk1_Disable(void);volatile U32 downloadAddress;void (*restart)(void)=(void (*)(void))0x0;volatile unsigned char *downPt;volatile U32 downloadFileSize;volatile U16 checkSum;volatile unsigned int err=0;volatile U32 totalDmaCount;volatile int isUsbdSetConfiguration;int download_run=0;U32 tempDownloadAddress;int menuUsed=0;extern char Image$$RW_RAM1$$RW$$Limit[]; U32 *pMagicNum=(U32 *)Image$$RW_RAM1$$RW$$Limit; int consoleNum;volatile U32 cpu_freq;volatile U32 UPLL;static void cal_cpu_bus_clk(void){  U32 val;U8 m, p, s;val = rMPLLCON;m = (val>>12)&0xff;p = (val>>4)&0x3f;s = val&3;//(m+8)*FIN*2 不要超出32位数!FCLK = ((m+8)*(FIN/100)*2)/((p+2)*(1<<s))*100;val = rCLKDIVN;m = (val>>1)&3;p = val&1;val = rCAMDIVN;s = val>>8;switch (m) {case 0:HCLK = FCLK;break;case 1:HCLK = FCLK>>1;break;case 2:if(s&2)HCLK = FCLK>>3;elseHCLK = FCLK>>2;break;case 3:if(s&1)HCLK = FCLK/6;elseHCLK = FCLK/3;break;}if(p)PCLK = HCLK>>1;elsePCLK = HCLK;if(s&0x10)cpu_freq = HCLK;elsecpu_freq = FCLK;val = rUPLLCON;m = (val>>12)&0xff;p = (val>>4)&0x3f;s = val&3;UPLL = ((m+8)*FIN)/((p+2)*(1<<s));UCLK = (rCLKDIVN&8)?(UPLL>>1):UPLL;}   char *mode;unsigned long distance;void Main(void){    int i;unsigned char  Pin;  //存放Echo输入值unsigned int   plu; //存放定时器4计数值U8 key;U32 mpll_val = 0 ;Port_Init();Isr_Init();i = 2 ;//don't use 100M!switch ( i ) {case 0://200key = 12;mpll_val = (92<<12)|(4<<4)|(1);break;case 1://300key = 13;mpll_val = (67<<12)|(1<<4)|(1);break;case 2://400key = 14;mpll_val = (92<<12)|(1<<4)|(1);break;case 3://440!!!key = 14;mpll_val = (102<<12)|(1<<4)|(1);break;default:key = 14;mpll_val = (92<<12)|(1<<4)|(1);break;}//init FCLK=400M, so change MPLL firstChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3);ChangeClockDivider(key, 12);cal_cpu_bus_clk();consoleNum = 0;// Uart 1 select for debug.Uart_Init( 0,115200 );Uart_Select( consoleNum );//Beep(2000, 100);Uart_SendByte('\n');Uart_Printf("<****************************************************>\n");Uart_Printf("               Ultrasonic ranging Test Program\n");Uart_Printf("                XIAO_PING_PING\n");Uart_Printf("<****************************************************>\n");rMISCCR=rMISCCR&~(1<<3); // USBD is selected instead of USBH1 rMISCCR=rMISCCR&~(1<<13); // USB port 1 is enabled.rDSC0 = 0x2aa;rDSC1 = 0x2aaaaaaa;//Enable NAND, USBD, PWM TImer, UART0,1 and GPIO clock,//the others must be enabled in OS!!!rCLKCON = 0xfffff0;MMU_Init();//pISR_SWI=(_ISR_STARTADDRESS+0xf0);//for pSOSmode="DMA";Clk0_Disable();Clk1_Disable();mpll_val = rMPLLCON;download_run=1; //The default menu is the Download & Run mode./****************配置GPG10和GPG11*************************************GPG10/EINT18接US100的Trig/Tx*GPG11/EINT19接US100的Echo/Rx**********************************************************************/    Init_Ultrasonic();   //US100端口初始化timer4_init();   //定时器4初始化   while(1){      rGPGDAT = rGPGDAT | (1<<10);   //给Trig高电平delay10us();rGPGDAT = rGPGDAT & ~(1<<10);   //给Trig低电平    timer4_init(); //100KHz计数器while(0 ==((rGPGDAT&(1<<11))>>11)&0x01) ;rTCON = (rTCON & ~(0x7<<20)) | (0x7<<20); //自动重载、手动更新、启动定时器4    rTCON = (rTCON & ~(0x2<<20));    //关闭手动更新rTCON = (rTCON & ~(0x4<<20));    //取消自动重载while(1 == ((rGPGDAT&(1<<11))>>11)&0x01)  ;plu = rTCNTO4;rTCON = (rTCON & ~(0x1<<20)) | (0x0<<20); //关闭定时器4Uart_Printf("100KHz计数值 = %d\n",25000-plu);distance = (25000-plu)*170*1000/100000;//计算距离,单位mmUart_Printf("超声波测量距离 = %dmm\n",distance);mdelay(100);}  }void Isr_Init(void){pISR_UNDEF=(unsigned)HaltUndef;pISR_SWI  =(unsigned)HaltSwi;pISR_PABORT=(unsigned)HaltPabort;pISR_DABORT=(unsigned)HaltDabort;rINTMOD=0x0;  // All=IRQ moderINTMSK=BIT_ALLMSK;  // All interrupt is masked.}void HaltUndef(void){Uart_Printf("Undefined instruction exception!!!\n");while(1);}void HaltSwi(void){Uart_Printf("SWI exception!!!\n");while(1);}void HaltPabort(void){Uart_Printf("Pabort exception!!!\n");while(1);}void HaltDabort(void){Uart_Printf("Dabort exception!!!\n");while(1);}void ClearMemory(void){int memError=0;U32 *pt;Uart_Printf("Clear Memory (%xh-%xh):WR",_RAM_STARTADDRESS,HEAPEND);pt=(U32 *)_RAM_STARTADDRESS;while((U32)pt < HEAPEND){*pt=(U32)0x0;pt++;}if(memError==0)Uart_Printf("\b\bO.K.\n");}void Clk0_Enable(int clock_sel){// 0:MPLLin, 1:UPLL, 2:FCLK, 3:HCLK, 4:PCLK, 5:DCLK0rMISCCR = rMISCCR&~(7<<4) | (clock_sel<<4);rGPHCON = rGPHCON&~(3<<18) | (2<<18);}void Clk1_Enable(int clock_sel){// 0:MPLLout, 1:UPLL, 2:RTC, 3:HCLK, 4:PCLK, 5:DCLK1rMISCCR = rMISCCR&~(7<<8) | (clock_sel<<8);rGPHCON = rGPHCON&~(3<<20) | (2<<20);}void Clk0_Disable(void){rGPHCON = rGPHCON&~(3<<18);// GPH9 Input}void Clk1_Disable(void){rGPHCON = rGPHCON&~(3<<20);// GPH10 Input}/******************************************************函数名:Init_Ultrasonic()功能:配置US100超声波模块端口输入参数:输出参数:*******************************************************/void Init_Ultrasonic(void){rGPGCON = rGPGCON & (~(3<<20)) | (1<<20);         //配置GPG10为GPIO输出rGPGCON = rGPGCON & (~(3<<22)) | (1<<22);         //配置GPG11为GPIO输出rGPGDAT = rGPGDAT & (~(3<<10)) | (0<<10);   //拉低GPG10和GPG11引脚rGPGCON = rGPGCON & (~(3<<22)) | (0<<22);         //配置GPG11为GPIO输入//rGPGUP  = rGPGUP  & (~(3<<10)) | (0<<10);     //使能GPG10和GPG11引脚上拉功能}/******************************************************函数名:delay10us()功能:10us纯延时(实际略大于10us),用于给Trig输出触发脉冲输入参数:输出参数:*******************************************************/void delay10us(void){    unsigned int i;for(i=0;i<50000;i++) ;}


2.timer.c文件如下

/**************************************************************** 文件名: timer.c 作者:小炼子 编写时间:2014.06.28 功能:定时器4初始化 编写原因:验证US100超声波测距模块在TQ2440板上的可行性,编写的定时器 ****************************************************************/#include "2440addr.h"#include "def.h"#include "timer.h"#define _ISR_STARTADDRESS 0x33ffff00#define pISR_TIMER4     (*(unsigned *)(_ISR_STARTADDRESS+0x58))void led_init(void){ //板载LED为GPB[5:8] rGPBCON = (rGPBCON & ~(0xfff<<10)) | (0x555<<10);  //rGPBCON为01 配置为输出 rGPBUP  = rGPBUP  | (0xff<<5); //rGPBUP为1   禁止上拉 rGPBDAT = rGPBDAT | (0xff<<5); //LED灯全关}void led_display(unsigned char data){ //0x0全灭 0xf全亮 0x01 0x02 0x04 0x80 各自灯亮 rGPBDAT = (rGPBDAT & ~(0xff<<5)) | ((~data) <<5);}void Delay_timer0(int time){U32 val = (PCLK>>3)/1000-1;rTCFG0 &= ~(0xff<<8);rTCFG0 |= 3<<8;//prescaler = 3+1rTCFG1 &= ~(0xf<<12);rTCFG1 |= 0<<12;//mux = 1/2rTCNTB3 = val;rTCMPB3 = val>>1;// 50%rTCON &= ~(0xf<<16);rTCON |= 0xb<<16;//interval, inv-off, update TCNTB3&TCMPB3, start timer 3rTCON &= ~(2<<16);//clear manual update bitwhile(time--) {while(rTCNTO3>=val>>1);while(rTCNTO3<val>>1);};}void timer4_init(void){    rSRCPND = rSRCPND | (0x1<<14);   //清空定时器4源请求    rINTPND = rINTPND | (0x1<<14);    //清空定时器4中断请求  //  rINTMSK =  rINTMSK & ~(0x1<<14);//打开定时器4中断        rINTMSK =  rINTMSK | (0x1<<14);//关闭定时器4中断    //定时器配制寄存器0     //定时器输入时钟频率 = PCLK / {预分频值+1} / {分频值}    //{预分频值} = 0~255 {分频值} = 2, 4, 8, 16     //100KHz:50MHz/(250*2)=50MHz/(500)    rTCFG0 = (rTCFG0 & ~(0xff<<8)) | (249<<8); // prescaler1:249    rTCFG1 = (rTCFG1 & ~(0xf<<16)) | (0x0<<16); //divider:2,0b0000        rTCNTB4 = 25000;  //让定时器4每隔0.25秒中断一次     //rTCON = (rTCON & ~(0x7<<20)) | (0x7<<20); //自动重载、手动更新、启动定时器4    //rTCON = (rTCON & ~(0x2<<20));    //关闭手动更新//rTCON = (rTCON & ~(0x4<<20));    //取消自动重载}  void  __irq timer4_ISR(void) { static int count; rSRCPND = rSRCPND | (0x1<<14); rINTPND = rINTPND | (0x1<<14); //每隔0.5秒LED灯亮一次 if (count == 0) {  led_display(0xf);       //LED亮  count = 1; } else if (count == 1) {    led_display(0x0);       //LED灭    count = 0; } }/*void Main(void){ led_init(); timer4_init();  pISR_TIMER4 = (U32)timer4_ISR;   while(1); }*/

0 0