|
在學習 GRBL 中,涉及到很多 AVR 中斷、串口等相關知識。參考資料 MAKE:AVR PROGRAMMING
如果單獨列出來,會減輕 學習 GRBL 的負擔。
*************************
AVR 中斷
*************************
064820grbjpinizr1rg9lu.jpg (24.99 KB, 下載次數: 146)
下載附件
2016-4-9 23:57 上傳
使用中斷,而不是 polling (輪詢方式),
One problem with polling in event loops is that there’s no concept of priority.
Handling multiple jobs at once is where interrupts excel.
Interrupts do just what they sound like—they interrupt the normal flow of the program.
When an interrupt is triggered, all of the variables that you’re using are stashed in memory and then a special function, called an interrupt service routine (ISRs), is run.
There are two flavors of external interrupts: the fancy interrupts, INT0 and INT1, and the pin-change interrupts.
065450g47qg6e72mj1e4ew.png (309.46 KB, 下載次數: 144)
下載附件
2016-4-9 23:57 上傳
The INT0 interrupt mechanism has more versatile triggering possibilities, allowing you trigger the interrupt on a rising voltage, a falling voltage, any change, or continuously for a low-voltage level.
there are only two of
these type interrupts: INT0 and INT1, on pins PD2 and PD3.
The PCINT system, on the other hand, allows you to treat every I/O pin on the AVR as an interrupt source if you so desire, but only detects changes (not their direction.
The pin-change interrupts are grouped together in banks, so it’s more accurate to say that there’s a pin-change interrupt for the “B” pins, one for the “C” pins, and one for the “D” pins.
We use pinmask registers to select which of the pins from within the bank we want to trigger the interrupt.
ISRs are special routines that run when their interrupt flag is set, and their interrupt vector is called.
這里,vector 表示 8位 無符號數,是地址。
070501u9bw5ycwiw6kli8t.jpg (17.33 KB, 下載次數: 157)
下載附件
2016-4-9 23:57 上傳
Pin-Change Interrupt Example
ISR(PCINT2_vect){
....
}
void initPinChangeInterrupt18(void){
PCICR |= (1 << PCIE2); /* set pin-change interrupt for D pins */
PCMSK2 |= (1 << PCINT18); /* set mask to look for PCINT18 / PD2 */
// PCMSK2 |= (1 << PD2); /* this will also work for the pin mask */
sei(); /* set (global) interrupt enable bit */
}
071405vcfzlyno7fn28fiy.jpg (12.66 KB, 下載次數: 166)
下載附件
2016-4-9 23:57 上傳
we’ll need to tell the AVR which pins we’d like for it to watch specifically.
This is done through the pin mask, which is just a normal 8-bit byte where the corresponding bit is set for each pin we’d like to be able to trigger the interrupt.
071640gi55z4l6vlvvgv6k.jpg (47.92 KB, 下載次數: 168)
下載附件
2016-4-9 23:57 上傳
So if we want to trigger on PD2 and PD4, we can set the pin mask one of two ways.
We can either use the pins’ PCINTxx aliases, or the normal PD2 type pin references.
For instance:
PCMSK2 |= ( (1 << PCINT18) | (1 << PCINT20) );
or
PCMSK2 |= ( (1 << PD2) | (1 << PD4) );
both do the same thing: configure the pin-change interrupt to trigger if either PD2 and PD4 changes state.
結論,3段式
071949irtlhv8vxxwutxts.jpg (72.52 KB, 下載次數: 145)
下載附件
2016-4-9 23:57 上傳
****************************
AVR 定時
*****************************
http://www.zg4o1577.cn/bbs/dpj-47869-1.html
使用定時器必須弄清的幾個概念
在MCU中(M16),定時器是獨立的一個模塊,M16有三個獨立的定時器模塊,即T/C0、T/C1和T/C2;其中T/C0和T/C2都是8位的定時器,而T/C1是一個16位的定時器。定時器的工作是獨立于CPU之外自行運行的硬件模塊。
1、定時器何時開始工作(或說計數)的?
當TCCR0!=0x00任何模式下,只要MCU一上電,T/C就開始計時工作。其實TCCR0主要是定時器的預分頻和波形模式、比較匹配模式的設置,說到預分頻,不得不提一下這個模塊,這個模塊是T/C0、T/C1共用的一個模塊,但可以有不同的分頻設置。
2、定時器是如何進行工作的:說到定時器的工作,不得不說三個個重要參數:TCNT0、OCR0,TIMSK,TCNT0是設置定時器的計時初始值,定時器開始工作后立即從TCNT0一直累加到0XFF,累加過程所消耗的時間就是我們需要的定時時間;OCR0是一個比較設定值,當TCNT0的值累計到OCR0時(TNCT0==OCR0),如果有開啟比較匹配中斷功能,那么此時就會產生比較中斷,所以,OCR0的值一般都是設置在TCNT0初始值和0XFF之間,之外的任何值都不會產生比較中斷。TIMSK是一個中斷使能位設置,就是我們需要計時器溢出中斷或是比較匹配中斷功能或兩者都要時就對TIMSK的相應寄存器位進行設置。
3、定時器的中斷使用,一個定時器可以有兩個中斷資源可利用,一個只溢出中斷,另一個是比較匹配中斷,如上面2所說的。想說明的溢出中斷子程序內一般要有重載TCNT0的初始值,否則,TCNT0就會從0X00開始累加計數到0XFF,所耗費的時間就不我們想要的時間。比較中斷就是當TCNT0==OCR0時,發(fā)生比較匹配中斷;所以,中斷子程序中一般只插入少量的處理代碼,否則,會發(fā)生所謂的中斷套嵌的現象,由于M16不支持中斷套嵌,這樣會使得中斷子程序中的部分代碼無法執(zhí)行,嚴重時會造成系統(tǒng)崩潰。
4、TCNT0和OCR0的值換算:對于8bit的計時器,TCNT0一般可以由下面的公式換算:
TCNT0=256-(TV*F)/N;
TV: 所想要設定的定時時間,單位,us
F: 晶振頻率(MHz)
N: 分頻因子
void init_timer1()
{
//TCCR1A T/C1控制寄存器A
// -----------------------------------------------------------------
// | COM1A1| COM1A0| COM1B1| COM1B0| COM1C1| COM1C0| WGM11 | WGM10 |
// -----------------------------------------------------------------
//TCCR1B T/C1控制寄存器B
// -----------------------------------------------------------------
// | ICNC1 | ICES1 | - | WGM13 | WGM12 |CS12 |CS11 |CS10 |
// -----------------------------------------------------------------
//TCCR1C T/C1控制寄存器C
// -----------------------------------------------------------------
// | FOC1A | FOC1B | FOC1C | - | - | - | - | - |
// -----------------------------------------------------------------
// COM1A1,COM1A0:通道A的比較輸出模式
// COM1B1,COM1B0:通道B的比較輸出模式
// COM1C1,COM1C0:通道C的比較輸出模式
// WGM13,WGM12,WGM11,WGM10:波型發(fā)生模式:
// 比較輸出模式(CTC模式),非PWM
// 00普通端口操作,OC1A/OC1B/OC1C未連接
// 01比較匹配時OC1A/OC1B/OC1C電平取反
// 10比較匹配時清零OC1A/OC1B/OC1C(輸出低電平)
// 11比較匹配時置位OC1A/OC1B/OC1C(輸出高電平)
// 比較輸出模式(CTC模式),快速PWM
// 00普通端口操作,OC1A/OC1B/OC1C未連接
// 01WGM13為0時同上,為1時 比較匹配時 OC1A電平取反,OC1B/OC1C保留
// 10比較匹配時OC1A/OC1B/OC1C清零,在TOP時OC1A/OC1B/OC1C置位
// 11比較匹配時OC1A/OC1B/OC1C置位,在TOP時OC1A/OC1B/OC1C清零
// 比較輸出模式(CTC模式),相位修正及相頻修正PWM
// 00普通端口操作,OC1A/OC1B/OC1C未連接
// 01WGM13為0:同上,為1時 比較匹配時 OC1A電平取反,OC1B/OC1C保留
// 10升序計數匹配時將OC1A/OC1B/OC1C清零,降序計數匹配時將OC1A/OC1B/OC1C置位
// 11升序計數匹配時將OC1A/OC1B/OC1C置位,降序計數匹配時將OC1A/OC1B/OC1C清零
//
// 模式 WGM1x 工作模式說明 TOP OCR1x更新時刻TOVn置位時刻
// 0 0000 普通模式 0xFFFF 立即 MAX
// 1 0001 8位相位修正PWM0x00FF TOP BOTTOM
// 2 0010 9位相位修正PWM0x01FF TOP BOTTOM
// 3 001110位相位修正PWM0x03FF TOP BOTTOM
// 4 0100 CTC OCRnA 立即 MAX
// 5 0101 8位快速PWM0x00FF TOP TOP
// 6 0110 9位快速PWM0x01FF TOP TOP
// 7 0111 10位快速PWM0x03FF TOP TOP
// 8 1000相位頻率修正PWM ICRn BOTTOM BOTTOM
// 9 1001相位頻率修正PWM OCRnA BOTTOM BOTTOM
// 10 1010 相位修正PWM ICRn TOP BOTTOM
// 11 1011 相位修正PWM OCRnA TOP BOTTOM
// 12 1100 CTC ICRn 立即 MAX
// 13 1101 保留 - - -
// 14 1110 快速PWM ICRn TOP TOP
// 15 1111 快速PWM OCRnA TOP TOP
// ICNC1:使能/禁止輸入捕捉噪聲抑制器
// ICES1:輸入捕獲觸發(fā)沿選擇,0為下降沿觸發(fā),1為上升沿觸發(fā)
// CS12,CS11,CS10:T/C0時鐘預分頻選擇
// 000:無時鐘,T/C不工作 001:1/1
// 010:1/8 011:1/64 100:1/256
// 101:1/1024110:外部T1腳下降沿驅動 111:外部T1腳上升沿驅動
// FOC1A,FOC1B,FOC1C:強制輸出比較通道A,B,C
TCCR1A = TCCR1B = TCCR1C = 0;
//TCNT1H,TCNT1L 定時/計數器1
//OCR1AH,OCR1AL 輸出比較寄存器1A
//OCR1BH,OCR1BL 輸出比較寄存器1B
//OCR1CH,OCR1CL 輸出比較寄存器1C
//ICR1H,ICR1L 輸入捕捉寄存器1
}
有個注意事項,
121331gr5bfwiffd8i3k8i.jpg (119.74 KB, 下載次數: 172)
下載附件
2016-4-9 23:57 上傳
看過很多實例代碼,沒有遵循上面的 位運算 ,都是 unreadable。
|
|