『壹』 求超聲波發生器的單片機源代碼
//設計:ch314156
//模塊使用方法:一個控制口發一個10US以上的高電平,就可以在接收口等待高電平輸出.
//一有輸出就可以開定時器計時,當此口變為低電平時就可以讀定時器的值,此時就為此次測
//距的時間,方可算出距離.如此不斷的周期測,就可以達到你移動測量的值了
//波特率9600(晶振12M)
#include <reg52.h>
#include <intrins.h> //調用 _nop_(); 延時函數
#define uchar unsigned char
#define uint unsigned int
sbit trigger=P2^0; //觸發引腳
sbit rx=P2^1; //接收引腳
sbit key=P3^6; //按鍵
unsigned char key_scan(void);
uchar chaoshengbo(void);
void uart_init(void);
void uart(uchar distance);
void chaoshengbo_init(void);
uchar distance; //距離
void main()
{
uart_init(); //串口初始化
chaoshengbo_init(); //超聲波初始化
uart('A') ; //串口發送'A'
while(1)
{
if (key_scan() == 1) //按鍵按下
{
distance = chaoshengbo(); //超聲波測距
uart(distance); //串口發送距離 單位厘米
}
}
}
unsigned char key_scan(void) //按鍵查詢
{
unsigned char on = 0,i;
while(1)
{
if(key==0) //判斷是否按下
{
for(i=0;i<100;i++); //軟體延時
if(key==0) //再次判斷是否按下
{
on = 1;
break; //跳出循環
}
}
}
while(key==0);
return 1;
}
void uart_init(void) //串口初始化,用的是T1
{
TMOD=TMOD & 0x0f | 0x20;
TH1=0Xfd; //波特率9600(晶振12M)
TL1=0Xfd;
TR1=1;
REN=1;
SM0=0;
SM1=1;
}
void uart(uchar distance) //發送一個位元組
{
SBUF = distance;
while(!TI);
TI = 0;
}
void chaoshengbo_init(void) //超聲波初始化
{
trigger = 0;
}
uchar chaoshengbo(void) //超聲波測距,返回厘米值
{
trigger=1; //給至少10us的高電平信號
_nop_();
_nop_();
_nop_(); //延時
_nop_();
_nop_();
_nop_();
TMOD=TMOD & 0xf0 |0x01; //T0初始化
TH0=0X0;
TL0=0X0;
trigger=0;
while(!rx); //等待上升沿
EA = 0; //關中斷
TR0=1; //開啟T0定時器
while(rx); //等待下降沿
TR0=0; //關閉T0定時器
EA = 1; //開中斷
return (TH0*256+TL0)*0.034/2; //計算距離 單位厘米
}
『貳』 要個計算機與單片機的串口通信上位機C語言程序
兄弟,下面是我自己寫的,希望給你幫助,把數據用Send_One_Uart()這個函數直接發送到串口就行了!最後求採納,哈哈!
//-----頭文件
#include<reg52.h>
//-----定義全局變數
unsigned char Temp;
/***************************************************
** 函數名稱: UART_Init
** 功能描述: 串口初始化函數
** 輸 入:無
** 輸 出: 無
** 說 明: 無
****************************************************/
void UART_Init(void)
{
SCON = 0x50; //-----SCON: 模式 1, 8-bit UART, 使能接收
TMOD |= 0x20; //-----TMOD: timer 1, mode 2, 8-bit 重裝
TH1 = 0xFD; //-----TH1: 重裝值 9600 波特率 晶振 11.0592MHz
TR1 = 1; //-----TR1: timer 1 打開
ES = 1; //-----打開串口中斷
EA = 1; //-----打開總中斷
}
/***************************************************
** 函數名稱: SendByte
** 功能描述: 發送位元組函數
** 輸 入:無
** 輸 出: 無
** 說 明: 無
****************************************************/
void SendByte(unsigned char dat)
{
SBUF = dat;
while(!TI);
TI = 0;
}
/***************************************************
** 函數名稱: SendStr
** 功能描述: 發送字元串函數
** 輸 入:無
** 輸 出: 無
** 說 明: 無
****************************************************/
void SendStr(unsigned char *s)
{
while(*s!='\0')
{
SendByte(*s);
s++;
}
}
/***************************************************
** 函數名稱: main
** 功能描述: 主函數
** 輸 入:無
** 輸 出: 無
** 說 明: 無
****************************************************/
void main (void)
{
UART_Init(); //-----串口初始化
while(1)
{
if(Temp=='H'&&'i')
{
Temp=0;
SendStr("hello");
}
}
}
/***************************************************
** 函數名稱: UART_SER
** 功能描述: 串口中斷服務子函數
** 輸 入:無
** 輸 出: 無
** 說 明: 無
****************************************************/
void UART_SER (void) interrupt 4 //-----串列中斷服務程序
{
if(RI) //-----判斷是接收中斷產生
{
RI=0; //-----標志位清零
Temp=SBUF; //-----讀入緩沖區的值
}
}
『叄』 嵌入式溫濕度感測器C語言代碼求幫忙注釋
#include "ioCC2430.h" //包含頭文件,相應的板子以及感測器一些信息
#include "hal.h"
#include <math.h>
//#include <intrins.h>
#include <stdio.h>
typedef union //定義聯合體,
{
unsigned int i;
float f;
} value; //定義聯合體類型名稱為value
#define noACK 0
#define ACK 1
#define STATUS_REG_W 0x06 //0x06 = 0000 0110
#define STATUS_REG_R 0x07 //0x07 = 0000 0111
#define MEASURE_TEMP 0x03 //0x03 = 0000 0011
#define MEASURE_HUMI 0x05 //0x05 = 0000 0101
#define RESET 0x1e //0x1e = 0001 1110
#define SDA P1_6 //定義SDA代表的是P1_6腳
#define SCL P1_7
#define begin P2_0
unsigned char d1,d2,d3,d4,d5,d6,d7; //定義無符號字元型變數
void Wait(unsigned int ms) //定義wait函數,主要用於軟體循環,延時作用
{
unsigned char g,k;
while(ms)
{
for(g = 0;g <= 167; g++)
{
for(k = 0;k <= 48; k++);
}
ms--;
}
}
void QWait() //1us的延時
{
asm("NOP"); //加入匯編操作語句,空操作,主要用於機器周期執行
asm("NOP");
asm("NOP");
asm("NOP");
asm("NOP");
asm("NOP");
asm("NOP");
asm("NOP");
asm("NOP");
asm("NOP");
asm("NOP");
}
void initUART(void) //初始化單片機的串口
{
IO_PER_LOC_USART0_AT_PORT0_PIN2345(); //具體函數的定義與用法,你得參考頭文件中的程序代碼了
IO_DIR_PORT_PIN(1, 6, IO_OUT);
IO_DIR_PORT_PIN(1, 7, IO_OUT);
//IO_IMODE_PORT_PIN(1, 6, IO_IMODE_TRI);
//IO_IMODE_PORT_PIN(1, 7, IO_IMODE_TRI);
IO_DIR_PORT_PIN(2, 0, IO_OUT);
IO_FUNC_PORT_PIN(2, 0, IO_FUNC_GIO);
//SET_MAIN_CLOCK_SOURCE(RC);
SET_MAIN_CLOCK_SOURCE(CRYSTAL);
UART_SETUP(0, 115200, HIGH_STOP); //設置傳輸數據的波特率115200
UTX0IF = 1;
U0CSR |= 0XC7; //U0CSR = U0CSR | 0x1010 0111 (進行位或操作)
IEN0 |= 0x84;
SDA = 1;
SCL = 0;
}
int putchar (int c) //定義輸入字元函數,給的參數是一個整型的數
{
if (c == '
') //判斷參數c的值是否和'
'的值相等
{
while (!UTX0IF); //執行的時候UTX0IF的值是0,此處不是很理解?
UTX0IF = 0; //給UTX0IF賦0
U0DBUF = 0x0d; //U0DBUF賦值0x0d = 0000 1011
}
while (!UTX0IF);
UTX0IF = 0;
return (U0DBUF = c); //如果c的值不是'
'也就是換行符的時候,將c的值傳遞到U0DBUF寄存器中
}
char s_write_byte(unsigned char value) //定義寫位元組函數(8位)
{
unsigned char i,error = 0;
for (i = 0x80;i > 0;i /= 2) //i 賦初始值0x80 = 128, 執行判斷是i > 0,執行語句是i = i / 2; 即i = 128,64,32,16,8,4,2,1,0.5(0),8位
{
if (i & value)
SDA = 1;
else
SDA = 0;
SCL = 1; //此時SCL埠處,也就是p1_7引腳處是高電平
QWait(); //因為寫入需要時間,所以程序之中加入下面幾條語句
QWait();
QWait();
QWait();
QWait();
SCL = 0; //使能p1_7眼角處低電平,使的數據寫入(具體需要看單片機控制晶元的手冊
asm("NOP");
asm("NOP");
}
SDA = 1;
SCL = 1;
asm("NOP");
error = SDA;
QWait();
QWait();
QWait();
SDA = 1;
SCL = 0;
return error;
}
char s_read_byte(unsigned char ack) //讀取數據,按照位元組位的順序讀取(8位)128 = 1000 0000 ,64 = 0100 0000, 32 = 0010 0000 ,16 = 0001 0000, 8 = 0000 1000, 4 = 0000 0100 , 2 = 0000 0010, 1 = 0000 0001
{
unsigned char i,val = 0;
SDA= 1;
for(i = 0x80;i > 0;i /= 2) //同上
{
SCL = 1;
if (SDA) //判斷SDA處是否有高電平
val = (val | i); //進行或操作
else
val = (val | 0x00);
SCL = 0;
QWait();
QWait();
QWait();
QWait();
QWait();
}
SDA = !ack;
SCL = 1;
QWait();
QWait();
QWait();
QWait();
QWait();
SCL = 0;
SDA = 1;
return val; //返回讀取到的數據,一個位元組,八位
}
void s_transstart(void) //傳輸使能函數,就是給控制器引腳處相應電平,使對應模塊工作
{
SDA = 1;
SCL = 0;
QWait();
QWait();
SCL = 1;
QWait();
QWait();
SDA = 0;
QWait();
QWait();
SCL = 0;
QWait();
QWait();
QWait();
QWait();
QWait();
SCL = 1;
QWait();
QWait();
SDA = 1;
QWait();
QWait();
SCL = 0;
QWait();
QWait();
}
void s_connectionreset(void) //復位操作函數
{
unsigned char i;
SDA = 1;
SCL = 0;
for(i = 0;i < 9; i++)
{
SCL = 1;
QWait();
QWait();
SCL = 0;
QWait();
QWait();
}
s_transstart(); //調用開始函數
}
char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode) //函數,主要統計傳輸的數據個數
{
unsigned er = 0;
unsigned int i,j;
s_transstart();
switch(mode)
{
case 3 :er += s_write_byte(3);
break;
case 5 :er += s_write_byte(5);
break;
default :break;
}
for(i = 0;i < 65535;i++)
{
for(j = 0;j < 65535;j++)
{if(SDA == 0)
{
break;
}
}
if(SDA == 0)
{
break;
}
}
if(SDA)
{
er += 1;
}
*(p_value) = s_read_byte(ACK);
*(p_value + 1) = s_read_byte(ACK);
*p_checksum = s_read_byte(noACK);
d6 = *(p_value);
d7=*(p_value + 1);
return er;
}
void calc_sth11(float *p_humidity ,float *p_temperature)//計算溫度值
{
const float C1 =- 4.0;
const float C2 =+ 0.0405;
const float C3 =- 0.0000028;
const float T1 =+ 0.01;
const float T2 =+ 0.00008;
float rh =* p_humidity;
float t =* p_temperature;
float rh_lin;
float rh_true;
float t_C;
t_C = t * 0.01 - 44.0 ;
rh_lin = C3 * rh * rh + C2 * rh + C1;
rh_true = (t * 0.01 - 40.0 - 25) * (T1 + T2 * rh) + rh_lin;
if(rh_true > 100)
{
rh_true = 100;
}
if(rh_true < 0.1)
{
rh_true = 0.1;
}
*p_temperature = t_C;
*p_humidity = rh_true;
}
void main() //主函數
{
value humi_val,temp_val; //聲明兩個聯合體變數
unsigned char error,checksum; //聲明兩個無符號的字元型變數
initUART(); //初始化串口
P1INP |= 0xC0; //初始化P1引腳 , 0xC0 = 1010 0000 ,使P1_7和P1_5引腳為1
begin = 0;
s_connectionreset();
while(1) //無限循環操作
{
error = 0;
error += s_measure((unsigned char*) &humi_val.i,&checksum,5); //讀入串口的數據進行溫度的計算
d1 = d6;
d2 = d7;
error += s_measure((unsigned char*) &temp_val.i,&checksum,3);
d3 = d6;
d4 = d7;
if(error != 0)
s_connectionreset();
else
{
humi_val.f = (float)humi_val.i;
temp_val.f = (float)temp_val.i;
humi_val.f = d1 * 256 + d2;
temp_val.f = d3 * 256 + d4;
calc_sth11(&humi_val.f,&temp_val.f);
printf("temp:%5.1fC humi:%5.1f%%
",temp_val.f,humi_val.f);
// printf("t1:%x h1:%x
",d1,d2);
//printf("t2:%x h2:%x
",d3,d4);
}
Wait(150);
}
}