要報名請按這裡
2014年3月11日 星期二
趨勢
很久以前曾購買"時鐘4位led",找東西時不小心浮上桌面,隨手銲一片洞洞板,線路如上圖,然後分別在89E58,Atmega16,Nuc100執行一樣功能的程序
笙泉89E58
atmel的Atmega16
新唐NUC100
由下面3支程序可看出,C 在跨平台上,真的很方便 主程式並沒有做甚麼改變,不同處只有各自的TIMER設定,GPIO設定及位(BIT)操作,我一直以來都是用8X51組合語言在寫程序,偶而用PIC16F5X組合語言,自從接觸到 LPC2103(ARM7)後,強烈感覺用C真的比組合語言輕鬆很多,深刻感覺大勢所趨 呵呵 ,另外 一個趨勢"ARDUINO"這個板子,對初學者應該很便利,個人感到快被"ARDUINO"淹沒, Atmel Atmega系列因"ARDUINO"而得以熱銷,對Atmel 是件好事, 但感覺好像有點怪怪的,你有感覺到嗎?
//89e58程序 IDE KEIL C
// Function:時鐘計時
// 基板:
#include "REG_MPC89L51-515.H"
#include "INTRINS.H"
// io port Description
#define _ONE P10 //個
#define _TWO P11 //拾
#define _THREE P12 //百
#define _FOUR P13 //千
#define KEY P42
const _7_seg[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xd8,0x80,0x90,0xff };
unsigned char time_cnt,min_cnt=43,hour_cnt=12,show_time=0;
unsigned char _1_sec_cnt=0x28 ; //一秒 計時
unsigned char scan_cnt=0X00; //顯示掃瞄的位數指標
unsigned char disp_0,disp_1,disp_2,disp_3;
bit _05sec,hour_sw=0;
//-------------------------------------------------
void Init_IRQ()
{
ET1 = 0x01; //Enable Timer Interrupt 1
TMOD = 0X10 ;
TH1 = 0X3C ;
TL1 = 0XB0 ;
EA = 0x01 ; //Enable All Interrupt
TR1 = 0X01 ; //START TIMER1
}
void Timer_Interrupt_1() interrupt 3
{
_1_sec_cnt -- ;
if (_1_sec_cnt==0) // 計算 1秒
{ time_cnt ++ ;
_1_sec_cnt=0x28 ;
}
if(_1_sec_cnt>=0x14) // 產生0.5 Sec
{_05sec=1;}
else {_05sec=0;}
if (time_cnt>=60) //每60秒進一
{ min_cnt+=1;
time_cnt=0;
}
if (min_cnt>=60) //每60分進一
{ hour_cnt+=1;
min_cnt=0;
}
TH1 = 0X3C ;
TL1 = 0XB0 ;
}
main()
{
Init_IRQ();
//-----------------------------------------------
while (1)
{
if (scan_cnt>3) scan_cnt=0x00;
switch(scan_cnt)
{case 0:
P2=0XFF;
_ONE=0x00;
_TWO=0x01;
_THREE=0X01;
_FOUR=0X01;
if (05sec==1) {P2= _7_seg[disp_0]&0x7f;}else {P2= _7_seg[disp_0]|0x80;}
// P2= _7_seg[disp_0] ;
scan_cnt ++ ;
break;
case 1:
P2=0XFF;
_ONE=0x01;
_TWO=0x00;
_THREE=0X01;
_FOUR=0X01;
if (05sec==1) {P2= _7_seg[disp_1]&0x7f;}else {P2= _7_seg[disp_1]|0x80;}
// P2= _7_seg[disp_1] ;
scan_cnt ++ ;
break;
case 2:
P2=0XFF;
_ONE=0x01;
_TWO=0x01;
_THREE=0X00;
_FOUR=0X01;
P2= _7_seg[disp_2] ;
scan_cnt ++ ;
break;
case 3:
P2=0XFF;
_ONE=0x01;
_TWO=0x01;
_THREE=0X01;
_FOUR=0X00;
P2= _7_seg[disp_3] ;
scan_cnt ++ ;
break;
}
disp_0 = time_cnt % 10 ;
disp_1 = (time_cnt/10)%10 ;
disp_2= (min_cnt%10);
disp_3 = (min_cnt/10)%10 ;
}
}
//----------------------------------------------------------------------------------------
//Atmega16 IDE AVR studio4.18#include "avr/interrupt.h"
#include "avr/iom16.h"
#include "avr/io.h"
const unsigned char _7_seg[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xd8,0x80,0x90,0xff };
unsigned char time_cnt,min_cnt=43,hour_cnt=12,show_time=0;
unsigned char _1_sec_cnt=0x28 ; //一秒 計時
unsigned char scan_cnt=0X00; //顯示掃瞄的位數指標
unsigned char disp_0,disp_1,disp_2,disp_3;
//USER_FLAG_a------------------
unsigned char flag_a=0x00;
unsigned char _05sec=1;
#define _ONE_OFF PORTB|=_BV(4) //個
#define _ONE_ON PORTB&=~_BV(4)
#define _TWO_OFF PORTB|=_BV(3) //拾
#define _TWO_ON PORTB&=~_BV(3)
#define _THREE_OFF PORTB|=_BV(2) //百
#define _THREE_ON PORTB&=~_BV(2)
#define _FOUR_OFF PORTB|=_BV(1) //千
#define _FOUR_ON PORTB&=~_BV(1)
ISR (TIMER0_OVF_vect)
{
TCNT0 = 0x3D; //reload counter value
_1_sec_cnt -- ;
if (_1_sec_cnt==0) // 計算 1秒
{ time_cnt ++ ;
_1_sec_cnt=0x28 ;
}
if(_1_sec_cnt>=0x14) // 產生0.5 Sec
{ flag_a|=_BV(_05sec);}
else
{flag_a&=~_BV(_05sec);}
if (time_cnt>=60) //每60秒進一
{ min_cnt+=1;
time_cnt=0;
}
if (min_cnt>=60) //每60分進一
{ hour_cnt+=1;
min_cnt=0;
}
}
void timer0_init(void)
{
TCCR0 = 0x00; //stop
TCNT0 = 0x3D; //set count
OCR0 = 0xC3; //set compare
TCCR0 = 0x05; //start timer
}
int main(void)
{
DDRA=0Xff;
PORTA=0Xff;
DDRB=0Xff;
PORTB=0Xff;
//stop errant interrupts until set up
cli(); //disable all interrupts
timer0_init();
MCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x01; //timer interrupt sources
sei(); //re-enable interrupts
//all peripherals are now initialized
while (1)
{
if (scan_cnt>3) scan_cnt=0x00;
switch(scan_cnt)
{case 0:
PORTA=0XFF;
_ONE_ON;
_TWO_OFF;
_THREE_OFF;
_FOUR_OFF;
if (bit_is_set(flag_a,_05sec)) {PORTA= _7_seg[disp_0]&0x7f;}
else {PORTA= _7_seg[disp_0]|0x80;}
// PORTA= _7_seg[disp_0] ;
scan_cnt ++ ;
break;
case 1:
PORTA=0XFF;
_ONE_OFF;
_TWO_ON;
_THREE_OFF;
_FOUR_OFF;
if (bit_is_set(flag_a,_05sec)) {PORTA= _7_seg[disp_1]&0x7f;}
else {PORTA= _7_seg[disp_1]|0x80;}
// led_segment= _7_seg[disp_1] ;
scan_cnt ++ ;
break;
case 2:
PORTA=0XFF;
_ONE_OFF;
_TWO_OFF;
_THREE_ON;
_FOUR_OFF;
PORTA= _7_seg[disp_2] ;
scan_cnt ++ ;
break;
case 3:
PORTA=0XFF;
_ONE_OFF;
_TWO_OFF;
_THREE_OFF;
_FOUR_ON;
PORTA= _7_seg[disp_3] ;
scan_cnt ++ ;
break;
}
disp_0 = time_cnt % 10 ;
disp_1 = (time_cnt/10)%10 ;
disp_2= (min_cnt%10);
disp_3 = (min_cnt/10)%10 ;
}
}
//-------------------------------------------------------------------------------
//新唐 Cortex M0 NUC100 IDE MDK KEIL 4.2
#include
#include "NUC1xx.h"
#include "Driver\DrvGPIO.h"
#include "Driver\DrvSYS.h"
#define led_segment GPB_DOUT
#define _ONE GPIOA->DOUT.DOUT4 //個
#define _TWO GPIOA->DOUT.DOUT5 //拾
#define _THREE GPIOA->DOUT.DOUT6 //百
#define _FOUR GPIOA->DOUT.DOUT7 //千
#define BIBI DOUT8
#define ON_BIBI GPIOB->DOUT.BIBI=0
#define OFF_BIBI GPIOB->DOUT.BIBI=1
#define KEY0 PIN15
const char _7_seg[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xd8,0x80,0x90,0xff };
unsigned char time_cnt,min_cnt=43,hour_cnt=12,show_time=0;
unsigned char _1_sec_cnt=0x28 ; //一秒 計時
unsigned char scan_cnt=0X00; //顯示掃瞄的位數指標
unsigned char disp_0,disp_1,disp_2,disp_3;
typedef struct
{
struct
{
__IO uint32_t bibi_1:1;
__IO uint32_t _05sec:1;
__IO uint32_t hour_sw:1;
__I uint32_t RESERVE:29;
} Config;
} UART_FLAG_T;
UART_FLAG_T User1;
// User1.Config.hit_one = 1;
signed char dump_num=0,bi_time=5;
unsigned char cnt0=0,cnt1=0,cnt2=0,auto_hit=0;
unsigned char cnt02=0,cnt12=0,cnt22=0,auto_hit2=0;
volatile uint32_t FLAG_0=0;
void TMR0_IRQHandler(void) // Timer0 interrupt subroutine
{
TIMER0->TISR.TIF =1;
////////////////////////////////////////
if (User1.Config.bibi_1==1)
{ bi_time--;
if(bi_time<=0)
{User1.Config.bibi_1=0;
bi_time=5;
OFF_BIBI ;
}
else
{ON_BIBI; }
}
_1_sec_cnt -- ;
if (_1_sec_cnt==0) // 計算 1秒
{ time_cnt ++ ;
_1_sec_cnt=0x28 ;
}
if(_1_sec_cnt>=0x14) // 產生0.5 Sec
{User1.Config._05sec=1;}
else {User1.Config._05sec=0;}
if (time_cnt>=60) //每60秒進一
{ min_cnt+=1;
time_cnt=0;
}
if (min_cnt>=60) //每60分進一
{ hour_cnt+=1;
min_cnt=0;
}
// TIMER0->TISR.TIF =1;
}
//
void Timer_initial(void)
{
/* Step 1. Enable and Select Timer clock source */
/* 切換IP模組的時鐘源 */
SYSCLK->CLKSEL1.TMR0_S = 0; //Select 12Mhz for Timer0 clock source
SYSCLK->APBCLK.TMR0_EN =1; //Enable Timer0 clock source
/* Step 2. Select Operation mode */
TIMER0->TCSR.MODE=1; //Select periodic mode for operation mode
/* Step 3. Select Time out period = (Period of timer clock input) * (8-bit Prescale + 1) * (24-bit TCMP)*/
TIMER0->TCSR.PRESCALE=0; // Set Prescale [0~255]
TIMER0->TCMPR = 300000 ; // Set TICR(TCMP) [0~16777215]
// (1/12000000)*(0+1)*(300000)= 250usec
/* Step 4. Enable interrupt */
TIMER0->TCSR.IE = 1;
TIMER0->TISR.TIF = 1; //Write 1 to clear for safty
NVIC_EnableIRQ(TMR0_IRQn); //Enable Timer0 Interrupt
/* Step 5. Enable Timer module */
TIMER0->TCSR.CRST = 1; //Reset up counter
TIMER0->TCSR.CEN = 1; //Enable Timer0
TIMER0->TCSR.TDR_EN=1; //
}
/*-----------*/
/* Main Function */
/*-----------*/
int main(void)
{
//volatile int32_t i32delay=1000;
/* SYSCLK =>12Mhz*/
UNLOCKREG();
SYSCLK->PWRCON.XTL12M_EN = 1 ;
while(SYSCLK->CLKSTATUS.XTL12M_STB==0);
SYSCLK->CLKSEL0.HCLK_S=0;
SYSCLK->CLKSEL0.STCLK_S=0;
//------------------------------------
GPIOA-> PMD.PMD4 = 0X03; // 設為雙向,和51_IO 相同
GPIOA-> PMD.PMD5 = 0X03; // 設為雙向,和51_IO 相同
GPIOA-> PMD.PMD6 = 0X03; // 設為雙向,和51_IO 相同
GPIOA-> PMD.PMD7 = 0X03; // 設為雙向,和51_IO 相同
GPIOB-> PMD.PMD0 = 0X03; // 設為雙向,和51_IO 相同
GPIOB-> PMD.PMD1 = 0X03; // 設為雙向,和51_IO 相同
GPIOB-> PMD.PMD2 = 0X03; // 設為雙向,和51_IO 相同
GPIOB-> PMD.PMD3 = 0X03; // 設為雙向,和51_IO 相同
GPIOB-> PMD.PMD4 = 0X03; // 設為雙向,和51_IO 相同
GPIOB-> PMD.PMD5 = 0X03; // 設為雙向,和51_IO 相同
GPIOB-> PMD.PMD6 = 0X03; // 設為雙向,和51_IO 相同
GPIOB-> PMD.PMD7 = 0X03; // 設為雙向,和51_IO 相同
//--設定time0 啟動time0中斷
Timer_initial();
//--設定time0 啟動time0中斷
GPB_DMASK=0xff00;
User1.Config.bibi_1=0;
while (1)
{
if (scan_cnt>3) scan_cnt=0x00;
switch(scan_cnt)
{case 0:
led_segment=0XFF;
_ONE=0x00;
_TWO=0x01;
_THREE=0X01;
_FOUR=0X01;
if(User1.Config._05sec==1){led_segment= _7_seg[disp_0]&0x7f;} //
else {led_segment= _7_seg[disp_0]|0x80;}
// led_segment= _7_seg[disp_0] ;
scan_cnt ++ ;
break;
case 1:
led_segment=0XFF;
_ONE=0x01;
_TWO=0x00;
_THREE=0X01;
_FOUR=0X01;
if(User1.Config._05sec==1){led_segment= _7_seg[disp_1]&0x7f;} //
else {led_segment= _7_seg[disp_1]|0x80;}
// led_segment= _7_seg[disp_1] ;
scan_cnt ++ ;
break;
case 2:
led_segment=0XFF;
_ONE=0x01;
_TWO=0x01;
_THREE=0X00;
_FOUR=0X01;
led_segment= _7_seg[disp_2] ;
scan_cnt ++ ;
break;
case 3:
led_segment=0XFF;
_ONE=0x01;
_TWO=0x01;
_THREE=0X01;
_FOUR=0X00;
led_segment= _7_seg[disp_3] ;
scan_cnt ++ ;
break;
}
disp_0 = time_cnt % 10 ;
disp_1 = (time_cnt/10)%10 ;
disp_2= (min_cnt%10);
disp_3 = (min_cnt/10)%10 ;
}
}
2014年2月24日 星期一
2014年2月18日 星期二
農曆過年前後在做甚麼
這是台製的24BIT ADC 不錯
1W LED 因為沒做散熱,塗上防水膠後,丟到水裡,用水冷
ST LINK 測試 ,便宜 方便只佔2隻腳
PIC24FJ (64PIN)自製轉接板
舊機器拔下來的MCU_51
STM32F (LQPG48)自製轉接板
參加瑞薩FB 得到的小禮物
nRF24L01 測試 ,很便宜
2014年1月2日 星期四
Nuc100 ADC 單週期掃描(single-cycle scan)
單週期掃描(single-cycle scan)
void InitADC(void)
{
/* Step 1. GPIO initial */
GPIOA->OFFD|=0x00030000; //ADC0 ADC1 Disable digital input path
SYS->GPAMFP.ADC0=1; //adc0 Set ADC function 將PA0 切到ADC0
SYS->GPAMFP.ADC1_AD12=1; //adc1 將PA1 切到ADC1
/* Step 2. Enable and Select ADC clock source, and then enable ADC module */
SYSCLK->CLKSEL1.ADC_S = 2; //Select 22Mhz for ADC
SYSCLK->CLKDIV.ADC_N = 1; //ADC clock source = 22Mhz/2 =11Mhz;
SYSCLK->APBCLK.ADC_EN = 1; //Enable clock source
ADC->ADCR.ADEN = 1; //Enable ADC module
/* Step 3. Select Operation mode */
ADC->ADCR.DIFFEN = 0; //single end input
ADC->ADCR.ADMD = 2; //single scan mode <<<< 單週期掃描
/* Step 4. Select ADC channel */
ADC->ADCHER.CHEN = 0x03; //選擇 ADC0 & ADC1
/* Step 5. Enable ADC interrupt */
ADC->ADSR.ADF =1; //clear the A/D interrupt flags for safe
ADC->ADCR.ADIE = 1; //must set "1"
// NVIC_EnableIRQ(ADC_IRQn);
/* Step 6. start convert */
ADC->ADCR.ADST=1;
}
int main (void)
{
InitADC();
ADC->ADCALR.CALEN=1;
while( (ADC->ADCALR.CALDONE)==0 ){} // 校正
//---------------------------------------------------------------
while(ADC->ADSR.ADF==0);
ADC->ADSR.ADF=1; //clear adf flag
cnt=ADC->ADDR[0].RSLT>>3; //取ADC0 轉換結果
cnt1=ADC->ADDR[1].RSLT>>3; //取ADC1 轉換結果
ADC->ADCR.ADST=1;
}
NUC100 ADC單一觸發模式
單一觸發模式 (程式片段)
void InitADC(void)
{
/* Step 1. GPIO initial */
GPIOA->OFFD|=0x00010000; //ADC0 ADC1 Disable digital input path
SYS->GPAMFP.ADC0=1; //adc0 Set ADC function
// SYS->GPAMFP.ADC1_AD12=1; //adc1
/* Step 2. Enable and Select ADC clock source, and then enable ADC module */
SYSCLK->CLKSEL1.ADC_S = 2; //Select 22Mhz for ADC
SYSCLK->CLKDIV.ADC_N = 1; //ADC clock source = 22Mhz/2 =11Mhz;
SYSCLK->APBCLK.ADC_EN = 1; //Enable clock source
ADC->ADCR.ADEN = 1; //Enable ADC module
/* Step 3. Select Operation mode */
ADC->ADCR.DIFFEN = 0; //single end input
ADC->ADCR.ADMD = 0; //single mode
/* Step 4. Select ADC channel */
ADC->ADCHER.CHEN = 0x01; // adc0
/* Step 5. Enable ADC interrupt */
ADC->ADSR.ADF =1; //clear the A/D interrupt flags for safe
ADC->ADCR.ADIE = 1; //must set "1"
// NVIC_EnableIRQ(ADC_IRQn);
/* Step 6. start convert */
ADC->ADCR.ADST=1;
}
int main (void)
{
InitADC();
ADC->ADCALR.CALEN=1; // 校正
while( (ADC->ADCALR.CALDONE)==0 ){}
//--------------------------------------------------------------//
while(ADC->ADSR.ADF==0);
ADC->ADSR.ADF=1; //clear adf flag
CNT=ADC->ADDR[0].RSLT>>3; //取ADC0值 , 捨棄最後3BIT ,且放入CNT
ADC->ADCR.ADST=1;
}
void InitADC(void)
{
/* Step 1. GPIO initial */
GPIOA->OFFD|=0x00010000; //ADC0 ADC1 Disable digital input path
SYS->GPAMFP.ADC0=1; //adc0 Set ADC function
// SYS->GPAMFP.ADC1_AD12=1; //adc1
/* Step 2. Enable and Select ADC clock source, and then enable ADC module */
SYSCLK->CLKSEL1.ADC_S = 2; //Select 22Mhz for ADC
SYSCLK->CLKDIV.ADC_N = 1; //ADC clock source = 22Mhz/2 =11Mhz;
SYSCLK->APBCLK.ADC_EN = 1; //Enable clock source
ADC->ADCR.ADEN = 1; //Enable ADC module
/* Step 3. Select Operation mode */
ADC->ADCR.DIFFEN = 0; //single end input
ADC->ADCR.ADMD = 0; //single mode
/* Step 4. Select ADC channel */
ADC->ADCHER.CHEN = 0x01; // adc0
/* Step 5. Enable ADC interrupt */
ADC->ADSR.ADF =1; //clear the A/D interrupt flags for safe
ADC->ADCR.ADIE = 1; //must set "1"
// NVIC_EnableIRQ(ADC_IRQn);
/* Step 6. start convert */
ADC->ADCR.ADST=1;
}
int main (void)
{
InitADC();
ADC->ADCALR.CALEN=1; // 校正
while( (ADC->ADCALR.CALDONE)==0 ){}
//--------------------------------------------------------------//
while(ADC->ADSR.ADF==0);
ADC->ADSR.ADF=1; //clear adf flag
CNT=ADC->ADDR[0].RSLT>>3; //取ADC0值 , 捨棄最後3BIT ,且放入CNT
ADC->ADCR.ADST=1;
}
訂閱:
文章 (Atom)







