#include <C8051F060.h> // SFR declarations
#include <stdio.h>
sfr16 RCAP2 = 0xCA; // Timer2 capture/reload
sfr16 TMR2 = 0xCC; // Timer2
#define BAUDRATE 56000 // Baud rate of UART in bps
#define SYSCLK 22118400L
sbit Trig = P3^0;
sbit Echo = P3^1;
void OSCILLATOR_Init (void);
void PORT_Init_UART0 (void);
void UART0_Init (void);
void PORT_Init (void);
void Delay(void);
void Timer0_Init(void);
void Count(void);
float s = 0; //超声波的距离
// 主函数开始:关闭开门狗,系统时钟初始化,UART端口初始化,UART初始化,定时器0初始化,I/O端口的初始化 以及 超声波功能实现
void main (void)
{
SFRPAGE = CONFIG_PAGE;
WDTCN = 0xDE; // Disable watchdog timer
WDTCN = 0xAD;
OSCILLATOR_Init (); // Initialize oscillator
PORT_Init_UART0 (); // Initialize crossbar and GPIO
UART0_Init (); // Initialize UART0
Timer0_Init();
PORT_Init();
//while (1)
// {
// 超声波测距开始
// Trig = 1;
// Delay (); //至少10uS
// Trig = 0;
// while(!Echo); //等待模块输出高电平
// TCON = 0x10; //启动计时器0
// while(Echo); //等待模块输出低电平
// TCON &=~0x10; //停止计时器,开始计算距离
// Count();
// PORT_Init_UART0 ();
printf("\ns=%f",s); //串口输出所计算的距离
Delay();
// }
}
void OSCILLATOR_Init (void)
{
int i; // Software timer
char SFRPAGE_SAVE = SFRPAGE; // Save Current SFR page
SFRPAGE = CONFIG_PAGE; // Set SFR page
OSCICN = 0x80; // Set internal oscillator to run
// at its slowest frequency
CLKSEL = 0x00; // Select the internal osc. as
// the SYSCLK source
// Initialize external crystal oscillator to use 22.1184 MHz crystal
OSCXCN = 0x67; // Enable external crystal osc.
for (i=0; i < 256; i++); // Wait at least 1ms
while (!(OSCXCN & 0x80)); // Wait for crystal osc to settle
CLKSEL = 0x01; // Select external crystal as SYSCLK
// source
SFRPAGE = SFRPAGE_SAVE; // Restore SFRPAGE
}
void PORT_Init_UART0 (void)
{
char SFRPAGE_SAVE = SFRPAGE; // Save Current SFR page
SFRPAGE = CONFIG_PAGE; // Set SFR page
P3MDOUT=0x00;
P3 |= 0x03; //配置P3.0 和 P3.1口为数字输入
P3MDOUT=0x01; //配置P3.0口为推挽输出
XBR0 = 0x04; // Enable UART0 将TX0和RX0引脚分别分配到P0.0和P0.1
XBR1 = 0x00; //内部资源不连接到端口1
XBR2 = 0x40; // Enable crossbar and weak pull-up
P0MDOUT |= 0x01; // Set TX pin to push-pull
P1MDOUT |= 0x40; // Set P1.6(LED) to push-pull
SFRPAGE = SFRPAGE_SAVE; // Restore SFR page
}
void UART0_Init (void)
{
char SFRPAGE_SAVE;
SFRPAGE_SAVE = SFRPAGE; // Preserve SFRPAGE
SFRPAGE = TMR2_PAGE;
TMR2CN = 0x00; // Timer in 16-bit auto-reload up timer
// mode
TMR2CF = 0x08; // SYSCLK is time base; no output;
// up count only
RCAP2 = - ((long) SYSCLK/BAUDRATE/16);
TMR2 = RCAP2;
TR2= 1; // Start Timer2
SFRPAGE = UART0_PAGE;
SCON0 = 0x50; // 8-bit variable baud rate;
// 9th bit ignored; RX enabled
// clear all flags
SSTA0 = 0x15; // Clear all flags; enable baud rate
// doubler (not relevant for these
// timers);
// Use Timer2 as RX and TX baud rate
// source;
TI0 = 1; // Indicate TX0 ready
SFRPAGE = SFRPAGE_SAVE; // Restore SFRPAGE
}
//延时函数,具体延长多长时间,待定,至少10us
void Delay (void)
{
int x;
for(x = 0; x<100; x++);
}
//定时器0的初始化
void Timer0_Init(void)
{
char SFRPAGE_SAVE = SFRPAGE; // Save Current SFR page
SFRPAGE = TIMER01_PAGE; // Set SFR page
TH0 = 0x00;
TL0 = 0x00; //将定时器0设置为16位,计算时间时访问TH0和TL0这两个寄存器
TMOD = 0x01; // Timer0 in 16-bit mode
CKCON = 0x02; // Timer0 uses a 1:48 prescaler
ET0=0; // 将中断源关闭
SFRPAGE = SFRPAGE_SAVE; // Restore SFR page
}
//计算超声波所测量距离
float count(void)
{
unsigned int time =0;
time = 256*TH0+TL0;
// printf("\n%u",time);
TH0 = 0x00;
TL0 = 0x00;
s = time*0.068; //time0系统时钟 单位CM
return s;
}
这个是利用C8051f60控制一个超声波模块的程序,但是我调了很久,都不能成功,请大家帮忙 谢谢!PS:单片机给超声波模块的Trig口一个高电平,计算Echo口相应的持续时间,就能计算出距离~ |