📄 led_matrix.c
字号:
/*!
* \file led_matrix.c
* \brief Driver code for LED Matrix
* \version $Revision: 1.3 $
* \author Anthony Huereca and Michael Norman
* Based off code from Defcon 15 Badge
* http://www.grandideastudio.com/portfolio/defcon-15-badge
*/
#include "led_matrix.h"
/*******************************************************************/
unsigned long *MessageAddress = (unsigned long *)0x0001FC00;
unsigned char *SpeedAddress = (unsigned char *)0x0001FD00;
const char SelectChar[] =
{
'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
'!','"','#','$','%','&','\'','(',')','*','+',',','-','.','/',':',';','<','>','=','?','@','^','_','{','}',
'|','0','1','2','3','4','5','6','7','8','9',' '
};
/*! ASCII Font Table for 5x5 Character Set */
const unsigned char FontTable [][5] =
{
{ 0b00000, 0b00000, 0b00000, 0b00000, 0b00000 }, // Space
{ 0b00000, 0b00000, 0b10111, 0b00000, 0b00000 }, // !
{ 0b00100, 0b00011, 0b00100, 0b00011, 0b00000 }, // "
{ 0b01010, 0b11111, 0b01010, 0b11111, 0b01010 }, // #
{ 0b10010, 0b10101, 0b11111, 0b10101, 0b01001 }, // $
{ 0b10011, 0b01011, 0b00100, 0b11010, 0b11001 }, // %
{ 0b01010, 0b10101, 0b10111, 0b01000, 0b11000 }, // &
{ 0b00000, 0b00100, 0b00011, 0b00000, 0b00000 }, // '
{ 0b00000, 0b01110, 0b10001, 0b00000, 0b00000 }, // (
{ 0b00000, 0b10001, 0b01110, 0b00000, 0b00000 }, // )
{ 0b01010, 0b00100, 0b11111, 0b00100, 0b01010 }, // *
{ 0b00000, 0b00100, 0b01110, 0b00100, 0b00000 }, // +
{ 0b00000, 0b10000, 0b01000, 0b00000, 0b00000 }, // ,
{ 0b00000, 0b00100, 0b00100, 0b00100, 0b00000 }, // -
{ 0b00000, 0b00000, 0b10000, 0b00000, 0b00000 }, // .
{ 0b10000, 0b01000, 0b00100, 0b00010, 0b00001 }, // /
{ 0b01110, 0b11001, 0b10101, 0b01110, 0b00000 }, // 0
{ 0b00000, 0b10010, 0b11111, 0b10000, 0b00000 }, // 1
{ 0b11001, 0b10101, 0b10101, 0b10010, 0b00000 }, // 2
{ 0b10001, 0b10101, 0b10101, 0b01010, 0b00000 }, // 3
{ 0b01100, 0b01010, 0b11111, 0b01000, 0b00000 }, // 4
{ 0b10011, 0b10101, 0b10101, 0b01001, 0b00000 }, // 5
{ 0b01110, 0b10101, 0b10101, 0b01000, 0b00000 }, // 6
{ 0b00001, 0b11001, 0b00101, 0b00011, 0b00000 }, // 7
{ 0b01010, 0b10101, 0b10101, 0b01010, 0b00000 }, // 8
{ 0b00010, 0b10101, 0b10101, 0b11110, 0b00000 }, // 9
{ 0b00000, 0b00000, 0b01010, 0b00000, 0b00000 }, // :
{ 0b00000, 0b10000, 0b01010, 0b00000, 0b00000 }, // ;
{ 0b00000, 0b00100, 0b01010, 0b10001, 0b00000 }, // <
{ 0b00000, 0b01010, 0b01010, 0b01010, 0b00000 }, // =
{ 0b00000, 0b10001, 0b01010, 0b00100, 0b00000 }, // >
{ 0b00010, 0b00001, 0b10101, 0b00101, 0b00010 }, // ?
{ 0b01110, 0b10001, 0b10101, 0b10101, 0b10110 }, // @
{ 0b11110, 0b00101, 0b00101, 0b11110, 0b00000 }, // A
{ 0b11111, 0b10101, 0b10101, 0b01010, 0b00000 }, // B
{ 0b01110, 0b10001, 0b10001, 0b10001, 0b00000 }, // C
{ 0b11111, 0b10001, 0b10001, 0b01110, 0b00000 }, // D
{ 0b11111, 0b10101, 0b10101, 0b10001, 0b00000 }, // E
{ 0b11111, 0b00101, 0b00101, 0b00001, 0b00000 }, // F
{ 0b01110, 0b10001, 0b10101, 0b11100, 0b00000 }, // G
{ 0b11111, 0b00100, 0b00100, 0b11111, 0b00000 }, // H
{ 0b00000, 0b10001, 0b11111, 0b10001, 0b00000 }, // I
{ 0b01000, 0b10001, 0b01111, 0b00001, 0b00000 }, // J
{ 0b11111, 0b00100, 0b01010, 0b10001, 0b00000 }, // K
{ 0b11111, 0b10000, 0b10000, 0b10000, 0b00000 }, // L
{ 0b11111, 0b00010, 0b00100, 0b00010, 0b11111 }, // M
{ 0b11111, 0b00010, 0b00100, 0b11111, 0b00000 }, // N
{ 0b01110, 0b10001, 0b10001, 0b01110, 0b00000 }, // O
{ 0b11111, 0b00101, 0b00101, 0b00010, 0b00000 }, // P
{ 0b01110, 0b10001, 0b01001, 0b10110, 0b00000 }, // Q
{ 0b11111, 0b00101, 0b01101, 0b10010, 0b00000 }, // R
{ 0b10010, 0b10101, 0b10101, 0b01001, 0b00000 }, // S
{ 0b00001, 0b00001, 0b11111, 0b00001, 0b00001 }, // T
{ 0b01111, 0b10000, 0b10000, 0b01111, 0b00000 }, // U
{ 0b00011, 0b01100, 0b10000, 0b01100, 0b00011 }, // V
{ 0b11111, 0b01000, 0b00100, 0b01000, 0b11111 }, // W
{ 0b10001, 0b01010, 0b00100, 0b01010, 0b10001 }, // X
{ 0b00001, 0b00010, 0b11100, 0b00010, 0b00001 }, // Y
{ 0b10001, 0b11001, 0b10101, 0b10011, 0b10001 }, // Z
{ 0b00000, 0b11111, 0b10001, 0b10001, 0b00000 }, // [
{ 0b00001, 0b00010, 0b00100, 0b01000, 0b10000 }, // (
{ 0b00000, 0b10001, 0b10001, 0b11111, 0b00000 }, // ]
{ 0b00000, 0b00010, 0b00001, 0b00010, 0b00000 }, // ^
{ 0b10000, 0b10000, 0b10000, 0b10000, 0b10000 }, // _
{ 0b00000, 0b00011, 0b00100, 0b00000, 0b00000 }, // '
{ 0b01000, 0b10101, 0b10101, 0b10101, 0b11110 }, // a
{ 0b11111, 0b10100, 0b10100, 0b10100, 0b01000 }, // b
{ 0b01100, 0b10010, 0b10010, 0b10010, 0b00000 }, // c
{ 0b01000, 0b10100, 0b10100, 0b10100, 0b11111 }, // d
{ 0b01110, 0b10101, 0b10101, 0b10101, 0b10110 }, // e
{ 0b00100, 0b11110, 0b00101, 0b00001, 0b00010 }, // f
{ 0b10010, 0b10101, 0b10101, 0b10101, 0b01110 }, // g
{ 0b11111, 0b00100, 0b00100, 0b11000, 0b00000 }, // h
{ 0b00000, 0b00000, 0b11101, 0b00000, 0b00000 }, // i
{ 0b00000, 0b10000, 0b01101, 0b00000, 0b00000 }, // j
{ 0b11111, 0b00100, 0b01010, 0b10001, 0b00000 }, // k
{ 0b00000, 0b10001, 0b11111, 0b10000, 0b00000 }, // l
{ 0b11110, 0b00001, 0b00110, 0b00001, 0b11110 }, // m
{ 0b11111, 0b00001, 0b00001, 0b00001, 0b11110 }, // n
{ 0b01110, 0b10001, 0b10001, 0b01110, 0b00000 }, // o
{ 0b11111, 0b00101, 0b00101, 0b00010, 0b00000 }, // p
{ 0b00010, 0b00101, 0b00101, 0b11111, 0b10000 }, // q
{ 0b11111, 0b00010, 0b00001, 0b00001, 0b00010 }, // r
{ 0b10010, 0b10101, 0b10101, 0b01001, 0b00000 }, // s
{ 0b00010, 0b01111, 0b10010, 0b10010, 0b00000 }, // t
{ 0b01111, 0b10000, 0b10000, 0b01111, 0b00000 }, // u
{ 0b00011, 0b01100, 0b10000, 0b01100, 0b00011 }, // v
{ 0b01111, 0b10000, 0b01100, 0b10000, 0b01111 }, // w
{ 0b10001, 0b01010, 0b00100, 0b01010, 0b10001 }, // x
{ 0b10011, 0b10100, 0b10100, 0b01111, 0b00000 }, // y
{ 0b10010, 0b11010, 0b10110, 0b10010, 0b00000 }, // z
{ 0b00110, 0b01111, 0b11110, 0b01111, 0b00110 }, // {
{ 0b10010, 0b01000, 0b00111, 0b01000, 0b10010 }, // |
{ 0b00100, 0b01110, 0b10101, 0b00100, 0b00100 }, // }
{ 0b11111, 0b11111, 0b11111, 0b11111, 0b11111 }, //
};
/*******************************************************************/
/*!
* Create the frame buffer to display on the LED's
*
* @param dataPtr String to scroll across
* @param fb Pointer to the frame buffer array
* @return length of frame buffer
*/
int create_fb(char *dataPtr, byte *fb)
{
int i, j;
for (i = 0; i < COLUMNS; i++) // add enough space as header to start text from bottom of matrix
fb[i] = 0x00;
while ( *dataPtr )
{
if ( (*dataPtr < 0x20) || (*dataPtr > 0x7E) ) // If non-printable character,
*dataPtr = 32; // Convert to a blank.
for (j = 0; j < 5; j++)
{
fb[i] = FontTable[*dataPtr - 32][j];
i++;
}
if (*dataPtr != 32) // if we're not printing a space
{
fb[i] = 0x00; // add a single blank line in between characters
i++;
}
else
i--; // remove a blank line to keep words closer together
dataPtr++;
}
for (j = 0; j < COLUMNS; j++, i++) // add enough space to completely scroll through the matrix
fb[i] = 0x00;
return i;
}
/*******************************************************************/
/*!
* Scroll a message across the LEDs
* Interrupts scrolling if detects a button slide down the left side
* @param dataPtr String to scroll across
*/
void LEDScroll(char *dataPtr)
{
int c, i, message_length;
unsigned char fb [MAX_MSG_LENGTH];
byte scroll_delay;
/* Set up Array */
message_length=create_fb(dataPtr,fb);
/* Display Message */
/* Turn on RTC Clock */
SCGC2_RTC=1;
/* Turn on RTC Interrupt */
rtc_init(8);
/* Send out Characters */
for (i = 0; i < (message_length - COLUMNS); i++)
{
if(SlideLeftDown())
{
PTAD = 0x00;
break;
}
scroll_delay = *SpeedAddress;
//scroll_delay=5;
while (--scroll_delay)
{
for (c = 0; c < COLUMNS; c++)
{
if (c < COLUMNS/2)
{
PTAD = 0x00;
PTED = ~(1 << c);
PTDD = 0xFF;
PTAD = fb[i+c];
}
else
{
PTAD = 0x00;
PTDD = ~(1 << c - (COLUMNS/2));
PTED = 0xFF;
PTAD = fb[i+c];
}
// Enter stop mode and wait for RTC wakeup
asm (stop #0x2000);
}
PTAD=0x00;
}
}
/* Turn off RTC Interrupt */
RTCSC = 0x00;
/* Turn off RTC Clock */
SCGC2_RTC=0;
}
/*******************************************************************/
/*!
* Scroll a message across the LEDs
* Interrupts scrolling if detects any button touched
* @param dataPtr String to scroll across
*/
void LEDScrollTouch(char *dataPtr)
{
int c, i, scroll_delay, message_length;
unsigned char fb [MAX_MSG_LENGTH];
/* Set up Array */
message_length=create_fb(dataPtr,fb);
/* Display Message */
/* Turn on RTC Clock */
SCGC2_RTC=1;
/* Wait for button to be depressed */
while(KeyPressed()) {
}
/* Turn on RTC Interrupt */
rtc_init(8);
/* Send out Characters */
for (i = 0; i < (message_length - COLUMNS); i++)
{
if(KeyPressed())
{
PTAD = 0x00;
break;
}
scroll_delay = *SpeedAddress;
while (--scroll_delay)
{
for (c = 0; c < COLUMNS; c++)
{
if (c < COLUMNS/2)
{
PTAD = 0x00;
PTED = ~(1 << c);
PTDD = 0xFF;
PTAD = fb[i+c];
}
else
{
PTAD = 0x00;
PTDD = ~(1 << c - (COLUMNS/2));
PTED = 0xFF;
PTAD = fb[i+c];
}
// Enter stop mode and wait for RTC wakeup
asm (stop #0x2000);
}
PTAD=0x00;
}
}
/* Turn off RTC Interrupt */
RTCSC = 0x00;
/* Turn off RTC Clock */
SCGC2_RTC=0;
}
/*******************************************************************/
/*!
* Scroll a message across the LEDs
* Interrupts scrolling if detects badge is shaking or touched
* @param dataPtr String to scroll across
*/
void LEDScrollShake(char *dataPtr)
{
int c, i, scroll_delay, message_length;
unsigned char fb [MAX_MSG_LENGTH];
long vertical=0;
long horizontal=0;
/* Set up Array */
message_length=create_fb(dataPtr,fb);
/* Set to 2g sensitivity */
AccelOn(1);
/* Turn on RTC Clock */
SCGC2_RTC=1;
/* Turn on RTC Interrupt */
rtc_init(8);
/* Display Message */
for (i = 0; i < (message_length - COLUMNS); i++)
{
vertical=ReadAcceleration(0x06);
horizontal=ReadAcceleration(0x05);
if(vertical>0xb00 || horizontal>0xb00 || LastKeyPressed()==8)
{
PTAD = 0x00;
break;
}
scroll_delay = *SpeedAddress;
while (--scroll_delay)
{
for (c = 0; c < COLUMNS; c++)
{
if (c < COLUMNS/2)
{
PTAD = 0x00;
PTED = ~(1 << c);
PTDD = 0xFF;
PTAD = fb[i+c];
}
else
{
PTAD = 0x00;
PTDD = ~(1 << c - (COLUMNS/2));
PTED = 0xFF;
PTAD = fb[i+c];
}
// Enter stop mode and wait for RTC wakeup
asm (stop #0x2000);
}
PTAD=0x00;
}
}
/* Turn off RTC Interrupt */
RTCSC = 0x00;
/* Turn off RTC Clock */
SCGC2_RTC=0;
}
/*******************************************************************/
/*!
* Writes out message without scrolling.
*/
void LEDWrite(char *dataPtr)
{
int c, i, message_length;
unsigned char fb [MAX_MSG_LENGTH];
int j=0;
for(i=0;i<MAX_MSG_LENGTH;i++)
{
fb[i]=0;
}
message_length=1;
/* Set up Array */
i=0;
while ( *dataPtr )
{
if ( (*dataPtr < 0x20) || (*dataPtr > 0x7E) ) // If non-printable character,
*dataPtr = 32; // Convert to a blank.
for (j = 0; j < 5; j++)
{
fb[i] = FontTable[*dataPtr - 32][j];
i++;
}
if (*dataPtr != 32) // if we're not printing a space
{
fb[i] = 0x00; // add a single blank line in between characters
i++;
}
else
i--; // remove a blank line to keep words closer together
dataPtr++;
}
message_length=i;
/* Display Message */
/* Turn on RTC Clock */
//SCGC2_RTC=1;
/* Turn on RTC Interrupt */
//rtc_init(8);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -