|
发表于 2012-1-10 08:58:23
|
显示全部楼层
"程序中速度调整没有就是没有"
since our professor insisted on being able to change speed, here is one implementation.
display_speedset() sets the frame rate at which the display is updated.
/*
*/
#include <avr/io.h> //we use gcc avr
#include <avr/interrupt.h> //we use tmr interrupt
//#include "gpio.h"
//hardware configuration
#define ROW_PORT PORTC //row leds driven by ROW_PORT. active high
#define ROW_DDR DDRC
#define ROWs 0xff
#define COL_PORT PORTD //column leds driven by COL_PORT. active low
#define COL_DDR DDRD
#define COLs 0xff
#define COL_PR 0x3c //duration for each col, in tmr ticks
//end hardware configuration
//define port related macros
#define IO_SET(port, bits) port |= (bits)
#define IO_CLR(port, bits) port &=~(bits)
#define IO_IN(ddr, bits) ddr &=~(bits)
#define IO_OUT(ddr, bits) ddr |= (bits)
//#include <mega16.h>
//#include <delay.h>
#define UPDATE_PAUSE 0 //statitionary image
#define UPDATE_FAST 1 //fast update
#define UPDATE_MEDIUM 5 //medium update speed
#define UPDATE_SLOW 10 //slow update speed
//default user isr
void tmr0_isr_default(void) {
}
void (* tmr0_isr_ptr) (void)=tmr0_isr_default; //tmr0 isr pointer
unsigned char _display_updatespeed=UPDATE_FAST; //display speed
volatile unsigned char _display_updatecount=0; //update count
const unsigned char char_7[]={0x10,0x38,0x7C,0xFE,0x38,0x38,0x38,0x38,
0x00, 0x00, 0x00, 0x00}; //four rows of blanks
//unsigned char disbuff[8];
//unsigned char /*line,*/row;
//unsigned char time_counter;
//unsigned char move_speed_ok;
//显示显示缓冲区中内容,2ms一行,一帧8行16ms,1秒内显示62.5帧。其实点亮就返回,基本不占用CPU的时间,利用率高
void display(void)
{
static unsigned char line=0;
static unsigned char start_line=0;
COL_PORT = 0xff; //PORTC = 0xFF; // 关闭显示,起到消隐作用
ROW_PORT = char_7[(start_line+line) % 12]; //PORTA = disbuff[line];
COL_PORT = ~(1<<line); //PORTC = ~(1<<line); // 点亮一行
if (++line >= 12 ) {
line = 0;
_display_updatecount+=1; //update count
if (_display_updatecount == _display_updatespeed) {
_display_updatecount = 0; //reset the update count
start_line+=1;
if (start_line >= 12) start_line = 0;
}
}
}
void display_speedset(unsigned char speed) {
_display_updatespeed = speed; //update the display speed
}
// Timer 0 比较匹配中断服务,2ms中断1次
//interrupt [TIM0_COMP] void timer0_comp_isr(void)
ISR(TIMER0_COMP_vect)
{
tmr0_isr_ptr(); //run the user isr
//display(); // 调用LED扫描显示一行
/* if (++time_counter >= 50) // 此处控制移动速度
{
time_counter = 0;
move_speed_ok = 1;
}
*/
}
void tmr0_init(unsigned char pr) {
// T/C0 初始化
//TCCR0=0x0B; // 内部时钟,64分频(4M/64=62.5KHz),CTC模式
TCCR0 = (0<<FOC0) | //no forced output
(0<<WGM00) | //ctc mode, wgm1..0 = 0b10
(0<<COM01) | (0<<COM00) | //com01..0 = 0b00 -> normal port operation
(1<<WGM01) | //ctc mode, wgm1..0 = 0b10
(0<<CS02) | (1<<CS01) | (1<<CS00) //cs2..0 = 0b011 -> Fosc/64
;
TCNT0=0x00; //reset the tmr/counter
//OCR0=0x7C; // OCR0 = 0x7C(124),(124+1)/62.5=2ms
OCR0 = pr; //set up the period
//TIMSK=0x02; // 允许T/C0比较匹配中断
TIMSK = (TIMSK & 0xfc) | //retain existing bits
(1<<OCIE0) | //output compare interrupt enabled
(0<<TOIE0) //tmr0 overflow interrupt disabled
;
//tmr0_isr_ptr = tmr0_isr_default; //install an empty isr routine
}
void tmr0_act(void (* funct_ptr)(void)) {
tmr0_isr_ptr = funct_ptr; //install user isr routine
}
//initialize the leds
void led_init(void) {
IO_CLR(ROW_PORT, ROWs); //clear rows - turn off the leds
IO_OUT(ROW_DDR, ROWs); //rows as output
IO_SET(COL_PORT, COLs); //set cols - turn off the leds
IO_OUT(COL_DDR, COLs); //cols as output
//PORTA=0x00;
//DDRA=0xFF;
//PORTC=0xFF;
//DDRC=0xFF;
}
void mcu_init(void) {
}
int main(void)
{
//unsigned char i,j = 0;
//initialize the leds
led_init();
//initialize the tmr
tmr0_init(COL_PR);
//for (i=0;i<=7;i++) {disbuff = char_7};
tmr0_act(display); //install display as user isr
display_speedset(UPDATE_PAUSE); //set the update speed
sei(); //enable global interrupt
while (1)
{
/*
if (move_speed_ok && line == 0);
{
move_speed_ok = 0;
for (i=0;i<=7;i++)
{
if (++j >= 12) j=0;
if (j<8)
disbuff = char_7[j];
else
disbuff = 0;
}
}
*/
}
return 0;
}
you can play around display_speedset() with different parameters, to get the update to go from totally stationary, to very very fast.
it also display four bank rows, as the professor insisted.
all of them are done in a modular way. display() is written so that it can be called from within an isr, or separately. |
|