外部中斷的常用功能
為企業(yè)提供成都做網(wǎng)站、成都網(wǎng)站建設(shè)、網(wǎng)站優(yōu)化、全網(wǎng)營(yíng)銷推廣、競(jìng)價(jià)托管、品牌運(yùn)營(yíng)等營(yíng)銷獲客服務(wù)。成都創(chuàng)新互聯(lián)公司擁有網(wǎng)絡(luò)營(yíng)銷運(yùn)營(yíng)團(tuán)隊(duì),以豐富的互聯(lián)網(wǎng)營(yíng)銷經(jīng)驗(yàn)助力企業(yè)精準(zhǔn)獲客,真正落地解決中小企業(yè)營(yíng)銷獲客難題,做到“讓獲客更簡(jiǎn)單”。自創(chuàng)立至今,成功用技術(shù)實(shí)力解決了企業(yè)“網(wǎng)站建設(shè)、網(wǎng)絡(luò)品牌塑造、網(wǎng)絡(luò)營(yíng)銷”三大難題,同時(shí)降低了營(yíng)銷成本,提高了有效客戶轉(zhuǎn)化率,獲得了眾多企業(yè)客戶的高度認(rèn)可!
外部中斷經(jīng)常用來(lái)記錄外部脈沖的個(gè)數(shù),也就是當(dāng)我們使用外部中斷1時(shí),如果想記錄自身單片機(jī)的某個(gè)引腳的下降沿個(gè)數(shù),只需用杜邦線把這個(gè)引腳和P3.3連接即可。
比如P2.3引腳產(chǎn)生這樣的電平無(wú)規(guī)律跳轉(zhuǎn),則下降沿的個(gè)數(shù)為5
所以我們就用外部中斷1來(lái)實(shí)現(xiàn)記錄K4按鍵從按下到松手的抖動(dòng)過(guò)程中經(jīng)歷了多少個(gè)下降沿,把下降沿的個(gè)數(shù)顯示在數(shù)碼管上。
2.程序思路
我們定義一個(gè)16位的全局變量pulse用來(lái)記錄P2.3下降沿的個(gè)數(shù),在中斷函數(shù)中的任務(wù)就是簡(jiǎn)單的pulse自加,因?yàn)橐_遇到下降沿就會(huì)進(jìn)入中斷函數(shù)。
在主函數(shù)里就是負(fù)責(zé)數(shù)碼管顯示即可。
3.代碼#include?
#include?//詳見(jiàn)第六章第8講
u16?pulse=0;
void?main()
{
u16?x,PULSE_buf;
IT1?=?1;???//下降沿觸發(fā)模式
EX1?=?1;
EA??=?1;
LED_Init();//初始化LED硬件模塊
KEY_Init();//初始化按鍵功能模塊
ShowNumber(pulse);
while(1)
{
SEG_Scan();
if(PULSE_buf!=pulse)ShowNumber(pulse);//pulse不再是前一次的值,也就是pulse數(shù)值更新了,所以數(shù)碼管緩存區(qū)也要更新pulse的數(shù)值以便顯示出來(lái)
x++;
if(x=50)//隔一段時(shí)間過(guò)來(lái)記錄此時(shí)的pulse數(shù)值
{
x=0;
PULSE_buf=pulse;
}
}
}
//請(qǐng)把P3.3和P2.3用杜邦線連接起來(lái)
void?EXTI1_IRQHandler()?interrupt?2
{
pulse++;
}
大家多按幾次K4,發(fā)現(xiàn)按下后松手的一個(gè)動(dòng)作里有時(shí)pulse就自加了幾次,顯示在數(shù)碼管上的數(shù)加了好幾下。
#include reg51.h
sbit pulse = P3^1;
void main (void)
{
P3=0xFF;
EA=1;
ET1=1;
TMOD =0x10;
TH1 = 0xFFH;
TL1 = 0xFFH;
TR1=1;
for(;;);
}
void intserv 3 (void) interrupt 3 using1
{
TH1 = 0xFFH;
TL1 = 0xFFH;
pulse=!pulse;
}
#include stdio.h
int main()
{
int breathe, pulse;
printf("Breathe: ");
scanf("%d", breathe);
printf("Pulse: ");
scanf("%d", pulse);
if (15 = breathe breathe =20
50 = pulse pulse = 70)
printf("sleeping\n");
else
printf("pretend\n");
return 0;
}
這個(gè)是主程序和部分代碼由于字?jǐn)?shù)限制所以你還是留個(gè)郵箱吧
void main(void)
{
unsigned char i;
sys_init();
beep = 1;
LCD12864_DisplayOneLine(0x80,ucStr1); //顯示信息1
LCD12864_DisplayOneLine(0x90,ucStr2); //顯示信息2
LCD12864_DisplayOneLine(0x88,ucStr3); //顯示信息3
LCD12864_DisplayOneLine(0x98,ucStr4); //顯示信息4
while(1)
{
sendDataToProcessing('S', Signal); // 發(fā)送并處理原始脈搏傳感器數(shù)據(jù)
if (QS == true){ // 確定發(fā)現(xiàn)一個(gè)心跳
fadeRate = 255; // Set 'fadeRate' Variable to 255 to fade LED with pulse
sendDataToProcessing('B',BPM); // 發(fā)送一個(gè)'B'和心率
sendDataToProcessing('Q',IBI); // send time between beats with a 'Q' prefix
QS = false; // reset the Quantified Self flag for next time
LCD_disp_list_char(2,4,DisBuff);//在LCD12864上顯示BPM
}
delay(138); // 延時(shí) 19.6ms
LCD_disp_list_char(4,4,DisBuff2);
//ledFadeToBeat();
if(Pressure100){
for(i=0;i8;i++){
delay(1000);}
if (Pressure100){
beep = 0;}}
if(BPM60|BPM100){
for(i=0;i9;i++){
delay(1000);}
if(BPM60|BPM100){
beep = 0;}
for(i = 0;i16;i++) //依次執(zhí)行寫(xiě)入操作
{
putchar(ucStr1[i]);
}
for(i = 0;i16;i++) //依次執(zhí)行寫(xiě)入操作
{
putchar(ucStr2[i]);
}
for(i=0;i3;i++)
{
putchar(DisBuff[i]);}
for(i = 0;i16;i++) //依次執(zhí)行寫(xiě)入操作
{
putchar(ucStr3[i]);
}
for(i = 0;i16;i++) //依次執(zhí)行寫(xiě)入操作
{
putchar(ucStr4[i]);
}
for(i=0;i4;i++)
{
putchar(DisBuff2[i]);}
}
}
//void ledFadeToBeat(){
// fadeRate -= 15; // set LED fade value
// fadeRate = constrain(fadeRate,0,255); // keep LED fade value from going into negative numbers!
// analogWrite(fadePin,fadeRate); // fade LED
// }
/******************************************************************************
函數(shù)名稱:GetADCResult
函數(shù)功能:獲取AD轉(zhuǎn)換結(jié)果函數(shù)
入口參數(shù):BYTE ch(通道選擇)
返回值:result(A/D轉(zhuǎn)換結(jié)果)
備注:無(wú)
*******************************************************************************/
unsigned int GetADCResult(BYTE ch)
{ unsigned int result; //AD轉(zhuǎn)換結(jié)果result
ADC_CONTR=0xf8; //清除ADC控制寄存器ADC CONTR的CHS2、CHS1、CHS0(清除通道選擇)
_nop_(); //設(shè)置ADC CONTR控制寄存器后,要加4個(gè)空操作延時(shí)才可以正確讀到ADC CONTR寄存器的值
_nop_();
_nop_();
_nop_();
ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START; //開(kāi)ADC電源,選擇AD轉(zhuǎn)換速率,并選擇AD通道,開(kāi)始AD轉(zhuǎn)換
_nop_(); //設(shè)置ADC CONTR控制寄存器后,要加4個(gè)空操作延時(shí)才可以正確讀到ADC CONTR寄存器的值
_nop_();
_nop_();
_nop_();
while (!(ADC_CONTR ADC_FLAG));//等待AD轉(zhuǎn)換結(jié)束
ADC_CONTR = ~ADC_FLAG; //關(guān)閉ADC
result=ADC_RES; //將AD轉(zhuǎn)換結(jié)果的高兩位賦給result
result=result8; //將result循環(huán)左移8位
result+=ADC_RESL; //將AD轉(zhuǎn)換結(jié)果的底8位加高兩位共10位給result
return result; //返回10位AD轉(zhuǎn)換結(jié)果
}
void sendDataToProcessing(char symbol, int dat ){
putchar(symbol); // symbol prefix tells Processing what type of data is coming
printf("%d\r\n",dat); // the data to send culminating in a carriage return
}
void UART_init(void)
{
TMOD = 0x20; //定時(shí)器工作在定時(shí)器1的方式2
PCON = 0x00; //不倍頻
SCON = 0x50; //串口工作在方式1,并且啟動(dòng)串行接收
TH1 = 0xFd; //設(shè)置波特率 9600
TL1 = 0xFd;
TR1 = 1; //啟動(dòng)定時(shí)器1
}
char putchar(unsigned char dat)
{
TI=0;
SBUF=dat;
while(!TI);
TI=0;
return SBUF;
}
void _nop_ (void)
{}
void T0_init(void){
// Initializes Timer0 to throw an interrupt every 2mS.
TMOD |= 0x01; //16bit TIMER
TL0=T0MS;
TH0=T0MS8;
TR0=1; //start Timer 0
ET0=1; //enable Timer Interrupt
EA=1; // MAKE SURE GLOBAL INTERRUPTS ARE ENABLED
}
void T1_init(void){
// Initializes Timer0 to throw an interrupt every 2mS.
TMOD |= 0x01; //16bit TIMER
TL1=T0MS2;
TH1=T0MS28;
TR1=1; //start Timer 0
ET1=1; //enable Timer Interrupt
EA=1; // MAKE SURE GLOBAL INTERRUPTS ARE ENABLED
}
void ADC_init(unsigned char channel)
{
P1ASF=ADC_MASKchannel; //選擇P1. channel作為A/D輸入來(lái)用
ADC_RES=0; //清除ADC結(jié)果寄存器RES
ADC_RESL=0; //清除ADC結(jié)果寄存器RESL
AUXR1 |= 0x04; //調(diào)整ADC格式的結(jié)果
}
void Timer1_rountine(void) interrupt 1
{}
unsigned int analogRead(unsigned char channel)
{
unsigned int result;
while (!(ADC_CONTR ADC_FLAG));//Wait complete flag
ADC_CONTR =!ADC_FLAG; //clear ADC FLAG
result=ADC_RES;
result=result8;
result+=ADC_RESL;
// ADC_CONTR|=channel|ADC_POWER|ADC_SPEEDLL|ADC_START;
return result;
}
// Timer 0中斷子程序,每2MS中斷一次,讀取AD值,計(jì)算心率值
void Timer0_rountine(void) interrupt 1
{
int N;
unsigned char i;
// keep a running total of the last 10 IBI values
unsigned int runningTotal = 0; // clear the runningTotal variable
EA=0; // 關(guān)定時(shí)器中斷
TL0=T0MS;
TH0=T0MS8; //重裝16位定時(shí)器初值
Pressure = (GetADCResult(PressurePin)); //****************
DisBuff2[3] = Pressure%10+48;//取個(gè)位數(shù)
DisBuff2[2] = Pressure%100/10+48; //取十位數(shù)
DisBuff2[1] = Pressure%1000/100+48; //百位數(shù) ***************
DisBuff2[0] = Pressure/1000+48;//取千位數(shù)
Signal = GetADCResult(PulsePin); // 讀脈搏傳感器
sampleCounter += 2; // 使用這個(gè)值跟蹤記錄脈搏時(shí)間間隔在ms級(jí)
N = sampleCounter - lastBeatTime; // 減上個(gè)節(jié)拍的時(shí)間來(lái)避免噪聲
// 找到脈搏波的波峰和波谷
if(Signal thresh N (IBI/5)*3){ // 如果脈搏傳感器輸出小于電源電壓一半 并且 消除噪聲時(shí)間小于 3/5個(gè)脈搏時(shí)間間隔
if (Signal Trough){ // 如果脈搏傳感器輸出小于波谷
Trough = Signal; // 跟蹤脈搏波的最低點(diǎn)
}
}
if(Signal thresh Signal Peak){ // 如果輸出大于電源電壓一半并且大于波峰
Peak = Signal; // 將新值設(shè)為波峰
} // 跟蹤脈搏波的波峰
if (N 250){ // 避免高頻噪聲
if ( (Signal thresh) (Pulse == false) (N (IBI/5)*3) ){
Pulse = true; // 當(dāng)檢測(cè)到一個(gè)脈搏時(shí)將脈搏標(biāo)志設(shè)為真
blinkPin=0; // 點(diǎn)亮脈搏燈
IBI = sampleCounter - lastBeatTime; // 測(cè)量?jī)蓚€(gè)脈搏的時(shí)間in mS
lastBeatTime = sampleCounter; // 跟蹤脈搏時(shí)間
if(secondBeat){ // 如果這是第二個(gè)脈搏
secondBeat = false; // 清除標(biāo)識(shí)
for(i=0; i=9; i++){ // 全部的數(shù)據(jù)作為真實(shí)脈搏BMP
rate[i] = IBI;
}
}
if(firstBeat){ // 如果是第一個(gè)脈搏
firstBeat = false; // 清除標(biāo)志
secondBeat = true; // 設(shè)置第二脈搏標(biāo)志
EA=1; //開(kāi)中斷
return; // IBI 值是不可靠的所以拋棄
}
for(i=0; i=8; i++){ // 移動(dòng)數(shù)據(jù)在rate數(shù)組中
rate[i] = rate[i+1]; // 頂替舊值
runningTotal += rate[i]; // 加上第九個(gè)新值
}
rate[9] = IBI; // 加最后的IBI到rate數(shù)組中
runningTotal += rate[9]; // 加上一個(gè)IBI到runningTotal
runningTotal /= 10; // 取平均值
BPM = 60000/runningTotal; // 一分鐘可以檢測(cè)到多少個(gè)心跳及 BPM!
if(BPM200)BPM=200; //限制BPM最高顯示值
if(BPM30)BPM=30; //限制BPM最低顯示值
DisBuff[2] = BPM%10+48;//取個(gè)位數(shù)
DisBuff[1] = BPM%100/10+48; //取十位數(shù)
DisBuff[0] = BPM/100+48; //百位數(shù)
if(DisBuff[0]==48)
DisBuff[0]=32;
QS = true; // 設(shè)置QS標(biāo)志
// QS FLAG IS NOT CLEARED INSIDE THIS ISR
}
}
if (Signal thresh Pulse == true){ // 當(dāng)電壓歸零節(jié)拍結(jié)束
blinkPin=1; // 熄滅脈搏燈
Pulse = false; // 重置脈搏標(biāo)識(shí)我們可以重新測(cè)
amp = Peak - Trough; // 得到脈搏波的峰峰值
thresh = amp/2 + Trough; // 設(shè)置thresh位脈搏峰峰值的一半
Peak = thresh; // 為下一次測(cè)試重置波峰
Trough = thresh;
}
if (N 2500){ //如果超過(guò)2.5秒沒(méi)有檢測(cè)到一個(gè)脈搏
thresh = 512; // 重新設(shè)置波谷
Peak = 512; // 重新設(shè)置波峰
Trough = 512; // 重新設(shè)置間隔
lastBeatTime = sampleCounter; // 把最后的節(jié)拍時(shí)間更新
firstBeat = true; // 重新設(shè)置標(biāo)志避免噪聲
secondBeat = false; // 當(dāng)我們得到心跳的時(shí)候
}
EA=1; // 開(kāi)中斷
}// end isr
名稱欄目:c語(yǔ)言中pulse函數(shù) c語(yǔ)言put函數(shù)
URL網(wǎng)址:http://muchs.cn/article28/doedcjp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供定制網(wǎng)站、手機(jī)網(wǎng)站建設(shè)、虛擬主機(jī)、自適應(yīng)網(wǎng)站、網(wǎng)站策劃、微信公眾號(hào)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)