?? main.c
字號:
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include "LightTalk2.h"
#include <avr/eeprom.h>
#define MER_SWC_NUM 5 /* 水銀開關(guān)切換幾次(延時判斷去毛刺)*/
#define DE_BURR_CNT 5 /* 水銀開關(guān)檢測(毛刺)周期 */
struct {
unsigned merSwitch : 1;//水銀開關(guān)狀態(tài)位 1 切換中 0 顯示中
unsigned deBurring : 1;//去毛刺檢測位 1 延時完成 0 延時中
unsigned left2right : 1;//顯示方向標(biāo)志位 1 左->右 0 右->左
unsigned printLeds : 1;//顯示延時位 1 顯示新led 0 現(xiàn)實(shí)中
unsigned periodNew : 1;//搖動周期更新位 1 更新 0 未更新
}SYSFLAG;
unsigned char gLedsPeriod = 0;//leds輸出周期
unsigned char g_timeLedsMS =0;//led顯示時間
unsigned char gDeburrCnt = 0;//水銀開關(guān)(毛刺)檢測周期
unsigned char gShakePeriod = 0;//搖動周期
#define LINE_NUM 32
INT2CHAR gDotArr[LINE_NUM];
//T/C1 中斷例程
volatile unsigned int gT1CountMS=0;//1ms計(jì)時
SIGNAL(TIMER1_COMPA_vect)
{
gT1CountMS++;
g_timeLedsMS++;
gDeburrCnt++;
if(gDeburrCnt > DE_BURR_CNT)/* 水銀開關(guān)(毛刺)檢測周期 */
{ gDeburrCnt=0;
SYSFLAG.deBurring = 1;/* 微動開關(guān)檢測 開 */
}
if(g_timeLedsMS >= gLedsPeriod)/* leds輸出周期 gLedsPeriod = gShakePeriod/LINE_NUM*/
{ g_timeLedsMS = 0;
SYSFLAG.printLeds = 1;
}
if(SYSFLAG.merSwitch == 1)/* 搖動周期 */
{ gShakePeriod = gT1CountMS;
gT1CountMS = 0;
SYSFLAG.periodNew = 1;/* 保證數(shù)據(jù)的原子性 */
}/*記錄兩次方向切換之間的時間<65536ms*/
}
void delayMs(int i)
{
for(;i>0;i--)
_delay_ms(1);
}
/*
*
* 程序名稱:整型I16,轉(zhuǎn)成位bit發(fā)送
* 輸入?yún)?shù):無符號整型I16
* 輸出參數(shù):無,{向串口輸出16bit字符,顯示輸入的整型數(shù)}
* 注意事項(xiàng):需要軟串口支持【擴(kuò)展:返送函數(shù)可以改進(jìn)成程序指針】
* lightTalk2.c->suart_Byte(x);
*/
void suartInt2bitPrint(unsigned int i16)
{ unsigned char i = 16;
suart_Byte('b');
while(i--)
{
if(i16 & 0x8000)
{
suart_Byte('1');
}else
{
suart_Byte('0');
}
i16<<=1;
}
suart_Byte('\n');
suart_Byte('\r');
}
/*
*
* 程序名稱:周期讀引腳電平值(低電平為真)(ledtouch,lighttalk2電路支持)
* 入口參數(shù):引腳端口地址【絕對地址,幾PORTD等】
* (*(volatile unsigned char *)(addrPin))
* 出口參數(shù):無符號字節(jié)(端口值,1白,0黑)
* 注意事項(xiàng):需計(jì)時器0 US 延時支持.
* LightTalk2.h->_runTimer0_TimeUS(x)....
*
* 原意是通過硬件計(jì)時監(jiān)測放電周期,結(jié)果
* 程序效果介于延時判斷和周期檢測方式合并,還可以優(yōu)化,減少檢測
* 時間。(×原理還需細(xì)化×)
*/
#define RD_PINS_TIME 7 /* 讀端口次數(shù),如果有效值大于一半,則為讀取到真 */
unsigned char ReadPinsAsLowInTimePeriod(unsigned int addrPin)
{ unsigned char i;
unsigned char RdVal[RD_PINS_TIME]={0};
unsigned char bitShift=0x01;
unsigned char bitStore=0;
unsigned char bit1Cnt=0;
for(i = 0 ; i < RD_PINS_TIME ; i++)
{ _runTimer0_TimeUS(180);
do
{ _breakTimer0OV();
RdVal[i] = (*(volatile unsigned char *)(addrPin));
/*通過SRAM絕對地址讀取端口,程序可擴(kuò)展*/
}while( !(RdVal[i] == 0xFF) );/*_breakTimer0OV() 讀取引腳1,檢測到高電平 下一步*/
/* 開始新檢測周期 */
_runTimer0_TimeUS(170);
do
{ RdVal[i] = (*(volatile unsigned char *)(addrPin));
if( !(RdVal[i] == 0xFF) )/* 讀取引腳0,檢測到低電平 */
{
break;
}
}_whileTimer0OV();
_stopTimer0();
}
/* 結(jié)算采樣數(shù)組,有效次數(shù)大于等于總采樣數(shù),*/
/* 則為采樣到亮點(diǎn) 1,否則黑點(diǎn) 0 */
for(char j=0;j<8;j++)
{
for(i = 0;i < RD_PINS_TIME;i++)
{
if( (RdVal[i] & bitShift ) == 0){bit1Cnt++;}
}
if(bit1Cnt >= (RD_PINS_TIME/2))bitStore |= bitShift;
bit1Cnt=0;
bitShift<<=1;
}
return bitStore;
}
/*
*
* 程序名稱:讀取led組值(ledtouch,lighttalk2)
* 入口參數(shù):無
* 出口參數(shù):無
* 注意事項(xiàng):需端口操作宏;Timer0硬件us查詢延時支持
* LightTalk2.h->_ledsAnode_High(LEDS0);// 陽極
* _ledsCathode_ChangeToOutputLow(LEDS0);// 陰極
* .......
* _runTimer0_TimeUS(250);.......
* typedef struct INT2CHAR;//整型<->字節(jié)2
* U8 ReadPinsAsLowInTimePeriod(U16);
* suartInt2bitPrint(U16);
*
*
*/
void readLeds(INT2CHAR *I2Cptr)
{
INT2CHAR i2cVal;
/********************************************************/
/* ISP有影響,除去下載線,效果ok */
/* 開背景光 Turn ON*/
_ledsAnode_High(LEDS0);/* 陽極 */
_ledsCathode_ChangeToOutputLow(LEDS0);/* 陰極 */
/* 反向偏執(zhí) 充電 */
_ledsAnode_Low(LEDS1);
_ledsCathode_ChangeToOutputHig(LEDS1);
_runTimer0_TimeUS(250);
_waitTimer0OV();
/* 反向偏執(zhí) 檢測光 */
_ledsCathode_ReadIO_Hi_Z(LEDS1);
_runTimer0_TimeUS(250);
_waitTimer0OV();
_runTimer0_TimeUS(250);
_waitTimer0OV();
i2cVal.i8[0]=ReadPinsAsLowInTimePeriod(LEDS1ADDR);
_ledsAnode_Low(LEDS0);/* 陽極 Turn OFF*/
_ledsCathode_ChangeToOutputHig(LEDS0);/* 陽極 */
/********************************************************/
/* ISP有影響,除去下載線,效果ok */
/* 開背景光 Turn ON*/
_ledsAnode_High(LEDS1);/* 陽極 */
_ledsCathode_ChangeToOutputLow(LEDS1);/* 陰極 */
/* 反向偏執(zhí) 充電 */
_ledsAnode_Low(LEDS0);
_ledsCathode_ChangeToOutputHig(LEDS0);
_runTimer0_TimeUS(250);
_waitTimer0OV();
/* 反向偏執(zhí) 檢測光 */
_ledsCathode_ReadIO_Hi_Z(LEDS0);
_runTimer0_TimeUS(250);
_waitTimer0OV();
_runTimer0_TimeUS(250);
_waitTimer0OV();
i2cVal.i8[1]=ReadPinsAsLowInTimePeriod(LEDS0ADDR);
_ledsAnode_Low(LEDS1);/* 陽極 Turn OFF*/
_ledsCathode_ChangeToOutputHig(LEDS1);/* 陽極 */
_ledsCathode_ChangeToOutputHig(LEDS0);/* 復(fù)位為輸出 */
I2Cptr->i16 = valPack(i2cVal);
//c2iVal.i16 = valPack(i2cVal);
//suartInt2bitPrint(c2iVal.i16);
}
int main(void)
{
unsigned char i='0',gCnt=0;
char mercurySwitch = 0;//水銀開關(guān)狀態(tài)變換計(jì)數(shù)(去毛刺)
unsigned int bitShift=0x0001;
iniLeds();
for(i=0;i<LINE_NUM;i++)
{
gDotArr[i].i16=~bitShift;
bitShift<<=1;
if(bitShift == 0)bitShift = 0x0001;
ledsTurnOn(valUnPack(gDotArr[i].i16));
_runTimer1_TimeMS(10);
_waitTimer1OV();
_stopTimer1();
}
for(i='0';i<'9';i++)
suart_Byte(i);
if(_rdKey(LOOPCTRL) == 0)
{
SYSFLAG.left2right = 0;
gCnt = 32;
}else
{
SYSFLAG.left2right = 1;
gCnt = 0;
}
SYSFLAG.merSwitch = 0;
SYSFLAG.periodNew = 0;
SYSFLAG.deBurring = 0;
gT1CountMS = 0;
g_timeLedsMS = 0;
gLedsPeriod = 20;
_runTimer1CTC(124);/* CTC -> 124等于1ms */
sei();
while(1)
{
if(_rdKey(STARTKEY) == 0)
{
for(i=0;i<32;i++)
{ readLeds(&gDotArr[i]);
delayMs(150);
}
}
/* 水銀開關(guān)反轉(zhuǎn) */
if(SYSFLAG.deBurring == 1)/* 水銀開關(guān)(毛刺)檢測周期 */
{ if(_rdKey(LOOPCTRL) == 0)
{ if(SYSFLAG.left2right == 1)/* 0 -> 1, 計(jì)數(shù),去毛刺后,標(biāo)志置位 */
{ mercurySwitch++; /* 取毛刺計(jì)時 */
if(mercurySwitch > (MER_SWC_NUM))
{ mercurySwitch=0;
SYSFLAG.left2right= 0;
SYSFLAG.merSwitch = 1;
}
}else/* 未在指定時間內(nèi)完成,則次數(shù)歸零 */
{
mercurySwitch=0;
}/* 按鍵0狀態(tài)1(按鍵1狀態(tài)0),啟動切換毛刺計(jì),如果在完成計(jì)時前
變成按鍵0狀態(tài)0(按鍵1狀態(tài)1)顯示狀態(tài),則復(fù)位
*/
}else
{ if(SYSFLAG.left2right == 0)/* 1 -> 0, 計(jì)數(shù),去毛刺后,標(biāo)志置位 */
{ mercurySwitch++;
if(mercurySwitch > (MER_SWC_NUM))//< (char)(0-(MER_SWC_NUM/2)))
{ mercurySwitch=0;
SYSFLAG.left2right = 1;
SYSFLAG.merSwitch = 1;
}
}else/* 未在指定時間內(nèi)完成,則次數(shù)歸零 */
{ mercurySwitch=0;
}
}
SYSFLAG.deBurring = 0;
}
/* 顯示區(qū) */
if(SYSFLAG.merSwitch == 1)
{ if(SYSFLAG.periodNew == 1)/* 狀態(tài)切換中,且周期已更新(保持原子性,在計(jì)時1中斷內(nèi)更新) */
{ SYSFLAG.periodNew = 0;
suart_Byte('0'+SYSFLAG.left2right);
SYSFLAG.merSwitch = 0;/* 狀態(tài)復(fù)位(顯示狀態(tài)) *//* 改進(jìn):搖臂周期需改進(jìn)成幾次求平均值 */
gLedsPeriod = gShakePeriod / (LINE_NUM + 5) ;/* 通過搖臂周期計(jì)算顯示周期 */
suart_Byte('0'+gShakePeriod/100); gShakePeriod%= 100;
suart_Byte('0'+gShakePeriod/10); gShakePeriod%= 10;
suart_Byte('0'+gShakePeriod); gShakePeriod = 0;
suart_Byte('\n');suart_Byte('\r');
// if(SYSFLAG.left2right == 1)/* 初始換顯示zhi,方向 */
// {
// gCnt =0;
// }else
// { gCnt =LINE_NUM-1;
// }
}
}else
{/* 顯示狀態(tài) */
if(SYSFLAG.printLeds == 1)/* 顯示Leds */
{ SYSFLAG.printLeds = 0;
if((SYSFLAG.left2right == 1) && (gCnt < 32-1))/* 分方向顯示,超出范圍不顯示? */
{
ledsTurnOn(valUnPack(gDotArr[gCnt++].i16));
}else if((SYSFLAG.left2right ==0) && (gCnt > 0))
{ ledsTurnOn(valUnPack(gDotArr[gCnt--].i16));
}/* 改進(jìn):需加入空區(qū)域回顯,使得邊界變化更好 */
else
{
_ledsAnode_Low(LEDS0);
_ledsAnode_Low(LEDS1);
LEDS0VAL = 0xff;
LEDS1VAL = 0xff;
}
}
}
}
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -