• 沒有找到結果。

單晶片實務運用

N/A
N/A
Protected

Academic year: 2022

Share "單晶片實務運用"

Copied!
21
0
0

加載中.... (立即查看全文)

全文

(1)

單晶片實務運用

主題: AD590 溫度量測

班級: 四電機二 A 學號: 4980J081 姓名: 史宗平

指導老師: 陳大道

(2)

一 一 一

一、、、、

AD590 AD590 溫度量測 AD590 AD590 溫度量測 溫度量測電路圖 溫度量測 電路圖 電路圖 電路圖

(3)

二二

二二、、、、程式程式程式程式內容內容內容 內容

EX11_1_ADC_Manual.c:

//

*********************************************************************

**

// File : EX11_1_ADC_Man.C

// Purpose : 練習如何叫 Microchip C30 提供的 ADC 函式庫 //

// 使用的函式 :

// ConfigIntTimer1( )

// OpenTimer1( )

// BusyADC10()

// CloseADC10()

// ConfigintADC10()

// ConvertADC10()

// OpenADC10()

// ReadADC10()

// SetChanADC10()

//

// 動作 :

// 將 LCD 初始化成 2 行 5*7 文字模式

// 使用 C30EVM_LCD.c 中的副程式顯示下列字串

//

// Exercise 11- ADC

// VR1:XXX VR2:YYY

//

// 將 Timer 1 規劃成 Period 為 1 ms 的 Timer

// 使用中斷的技巧 , 在 ISR 檢查是否已計時 1 秒

// 若是 , 則進行類比訊號轉換,並將轉換結果顯示於

LCD //

//

//

*********************************************************************

(4)

**

#define __dsPIC30F4011__

#include <p30F4011.h>

#include "C30EVM_LCD.h" // 將 LCD 函式的原型宣告檔案含入

#include <timer.h> // 將 Timer 函式的原型宣告檔案含入

#include <adc10.h> // 將 adc10 函式的原型宣告檔案含入

#define FCY 7372800 * 2 // 因為使用頻率為將外部 7.3728 MHz * 8 的模式 , 每一指令週期需 4 個 clock

// 所以 FCY = (7.3728 * 8 / 4 ) MHz = 7372800* 2

_FOSC(CSW_FSCM_OFF & XT_PLL8); // XT with 8xPLL oscillator, Failsafe clock off

_FWDT(WDT_OFF); // Watchdog timer disabled

_FBORPOR(PBOR_OFF & MCLR_EN); // Brown-out reset disabled, MCLR reset enabled

_FGS(CODE_PROT_OFF); // Code protect disabled

const char My_String1[]="Exercise 11- ADC" ; // 宣告字串於 Program Memory (因為 const 宣告)

char My_String2[]="VR1: VR2: " ; // 宣告字串於 Data Memory

unsigned int miliSec ;

void Init_ADC(void) ; void Show_ADC(void) ;

// union 宣告將使 8 位元變數 ByteAccess 與 SystemFlag 結構變數使用相同的記憶 體,

// 以利不同格式的位元運算需求

union {

unsigned char ByteAccess ; struct {

unsigned Bit0: 1 ; unsigned Bit1: 1 ;

(5)

unsigned Bit2: 1 ; unsigned unused : 5 ; } ;

} SystemFlag ;

//定義 OneSecond 旗標等同於 SystemFlag.Bit0 位元變數,故將其使用一個位元記 憶空間

#define OneSecond SystemFlag.Bit0

void _ISR _T1Interrupt(void) //Timer1中斷副程式 {

miliSec += 1 ;

if (miliSec == 1000) //每 1000 次將 OneSecond 旗標設定為 1 {

OneSecond = 1 ; miliSec = 0 ; }

IFS0bits.T1IF = 0 ; //清除中斷旗標

}

int main( void ) {

Init_ADC( ) ; // 將 ADC 進行初始

化設定

OpenLCD( ) ; // 使用 OpenLCD( )

對 LCD 模組作初始化設定

// 4 bits Data mode

// 5 * 7 Character

setcurLCD(0,0) ; // 使用 setcurLCD( )

設定游標於 (0,0)

(6)

putrsLCD( My_String1 ) ; // 將存在 Program

Memory 的字串使用

// putrsLCD( ) 印出至 LCD

setcurLCD(0,1) ; // 使用 setcurLCD( )

設定游標於 (0,1)

putrsLCD( My_String2 ) ; // 將存在 Data Memory

的字串使用

// putsLCD( ) 印出至 LCD

ConfigIntTimer1( T1_INT_PRIOR_7 & T1_INT_ON ) ; // Timer1 的中斷優 先等級設 7 (最高)

// Timer1 的中 斷 ON

OpenTimer1( T1_ON & T1_IDLE_STOP & T1_GATE_OFF & // Timer1 的 Period 設為每 1ms

T1_PS_1_1 & T1_SYNC_EXT_OFF & T1_SOURCE_INT , (FCY/ 1000) ) ;

OneSecond = 0 ;

while(1) {

if ( OneSecond ) // 詢問 Timer1 的

Period 時間是否已到

// 可以用軟體

模擬來檢查是否為準確的 1 ms {

OneSecond = 0 ;

Show_ADC( ) ; // 將類比轉換結果

顯示於 LCD 上

} }

(7)

}

/***********************************************/

// Subroutine to configure the A/D module

void Init_ADC(void) {

unsigned int Channel, PinConfig, Scanselect, Adcon3_reg, Adcon2_reg, Adcon1_reg;

ADCON1bits.ADON = 0; /* turn off ADC */

PinConfig = ENABLE_AN0_ANA; // Select port pins as analog inputs ADPCFG<15:0>

Adcon1_reg = ADC_MODULE_ON & // Turn on A/D module (ADON) ADC_IDLE_STOP & // ADC turned off during idle (ADSIDL)

ADC_FORMAT_INTG & // Output in integer format (FORM) ADC_CLK_MANUAL & // Conversion trigger manually (SSRC)

ADC_SAMPLE_INDIVIDUAL & // Sample channels individually (SIMSAM)

ADC_AUTO_SAMPLING_OFF; // Sample trigger manually (ASAM)

Adcon2_reg = ADC_VREF_AVDD_AVSS & // Voltage reference : +AVdd, -AVss (VCFG)

ADC_SCAN_OFF & // Scan off (CSCNA)

ADC_ALT_BUF_OFF & // Use fixed buffer (BUFM) ADC_ALT_INPUT_OFF & // Does not alternate between MUX A & MUX B (ALTS)

ADC_CONVERT_CH0 & // Convert only channel 0 (CHPS) ADC_SAMPLES_PER_INT_1; // 1 sample between interrupt (SMPI)

Adcon3_reg = ADC_SAMPLE_TIME_10 & // Auto-Sample time (SAMC) ADC_CONV_CLK_SYSTEM & // Use system clock (ADRC)

(8)

ADC_CONV_CLK_4Tcy; // Conversion clock = 4 Tcy (ADCS) // ADCS = 2*(154ns)/(1/Fcy)-1 = 3.5416

Scanselect = SCAN_NONE; // ADC scan no channel (ADCSSL)

OpenADC10(Adcon1_reg, Adcon2_reg, Adcon3_reg, PinConfig, Scanselect);

Channel = ADC_CH0_POS_SAMPLEA_AN0 & // CH0 Pos. : AN0, Neg. : Nominal Vref- Defined in ADCON2

ADC_CH0_NEG_SAMPLEA_NVREF ; // (ADCHS) SetChanADC10(Channel);

ConfigIntADC10(ADC_INT_DISABLE); // Disable ADC interrupt

}

/***********************************************/

// Subroutine to show Time on LCD

void Show_ADC(void) {

unsigned char dummy ; unsigned int ADCValue;

float T;

ADCON1bits.SAMP = 1; // start sampling ...

for ( dummy = 0 ; dummy < 100 ; dummy ++ );

ConvertADC10();

while (BusyADC10()); // conversion done?

//ADCValue = (ADCBUF0 >> 2); // get ADC value T=(50.0/1023.0)*ADCBUF0;

ADCValue=T*10;

setcurLCD(12,1) ; // Set LCD cursor

put_Num_LCD( ADCValue ) ; // 將類比轉換結果以十進位數字顯示至液晶顯

(9)

示器

C30EVM_LCD.c:

#include "C30EVM_LCD.h"

#include <p30F4011.h>

//

// Defines for I/O ports that provide LCD data & control

// PORTD[0:3]-->DB[4:7]: Higher order 4 lines data bus with bidirectional // : DB7 can be used as a BUSY flag

// PORTA,1 --> [E] : LCD operation start signal control // PORTA,2 --> [RW]: LCD Read/Write control

// PORTA,3 --> [RS]: LCD Register Select control

// : "0" for Instrunction register (Write), Busy Flag (Read) // : "1" for data register (Read/Write)

//

#define CPU_SPEED 16 // CPU speed is 16 Mhz !!

#define LCD_RS LATFbits.LATF0 // The definition of control pins

#define LCD_RW LATFbits.LATF1

#define LCD_E LATBbits.LATB7

#define LCD_E_MODE ADPCFGbits.PCFG7 // Set RB7 as digital I/O

#define DIR_LCD_RS TRISFbits.TRISF0 // Direction of control pins

#define DIR_LCD_RW TRISFbits.TRISF1

#define DIR_LCD_E TRISBbits.TRISB7

#define LCD_DATA LATD // PORTD[0:3] as LCD DB[4:7]

#define DIR_LCD_DATA TRISD // Direction of Databus

// LCD Module commands --- These settings can be found in the LCD datasheet

#define DISP_2Line_8Bit 0x0038 // 2 lines & 8 bits setting

#define DISP_2Line_4Bit 0x0028 // 2 lines & 4 bits setting

(10)

#define DISP_ON 0x00C // Display on

#define DISP_ON_C 0x00E // Display on, Cursor on

#define DISP_ON_B 0x00F // Display on, Cursor on, Blink cursor

#define DISP_OFF 0x008 // Display off

#define CLR_DISP 0x001 // Clear the Display

#define ENTRY_INC 0x006 // Entry Increment and Cursor Move

#define ENTRY_INC_S 0x007 // Entry Increment and Display Shift

#define ENTRY_DEC 0x004 // Entry Decrement and Cursor Move

#define ENTRY_DEC_S 0x005 // Entry Decrement and Display Shift

#define DD_RAM_ADDR 0x080 // Least Significant 7-bit are for address

#define DD_RAM_UL 0x080 // Upper Left coner of the Display

unsigned char Temp_CMD ; // Temperary Buffers for Command, unsigned char Str_Temp ; // for String,

int Temp_LCD_DATA ; // for PORT data (This will be restored after Communication w/ LCD)

//unsigned char Out_Mask ; //

void OpenLCD(void)

{

Temp_LCD_DATA = LCD_DATA ; // Save the Port Value of LCD_DATA

LCD_E_MODE =1 ; // Initialize RB7 as digital I/O

LCD_E = 0 ; //

LCD_DATA &= 0xfff0; // LCD DB[4:7] & RS & R/W -->

Low

DIR_LCD_DATA &= 0xfff0; // LCD DB[4:7} & RS & R/W are output function

DIR_LCD_E = 0; // Set E pin as output

DIR_LCD_RS = 0 ; DIR_LCD_RW = 0 ;

(11)

// Initialize the LCD following the standard operations // 1st

LCD_DATA &= 0xfff0 ; // Clear PORTDbits.RD0 ~ RD3 but save others by &

LCD_DATA |= 0x0003 ; // Send Data of 0x03 but keep others by |

LCD_CMD_W_Timing() ; // LCD Command Write Sequence Function

LCD_L_Delay() ; // Delay for long enough time

(4.1ms minimum)

// 2nd

LCD_DATA &= 0xfff0 ; // Clear PORTDbits.RD0 ~ RD3 LCD_DATA |= 0x0003 ; // Send Data of 0x03

LCD_CMD_W_Timing() ; // LCD Command Write Sequence Function

LCD_L_Delay() ; // Delay for long enough time

(100us minimum)

// 3rd

LCD_DATA &= 0xfff0 ; // Clear PORTDbits.RD0 ~ RD3 LCD_DATA |= 0x0003 ; // Send Data of 0x03

LCD_CMD_W_Timing() ; // LCD Command Write Sequence Function

LCD_L_Delay() ; // Delay for long enough time

(Not Required)

LCD_DATA &= 0xfff0 ; // Clear PORTDbits.RD0 ~ RD3 LCD_DATA |= 0x0002 ; // Send Data of 0x02 for 4-bit databus interface

LCD_CMD_W_Timing() ; LCD_L_Delay() ;

WriteCmdLCD(DISP_2Line_4Bit) ; // Configure LCD - 2 lines display &

4-bit long bus

LCD_S_Delay() ;

WriteCmdLCD(DISP_ON) ; // Configure LCD - Turn on display

LCD_S_Delay() ;

(12)

WriteCmdLCD(ENTRY_INC) ; // Configure LCD - Entry increment (to the right)

LCD_S_Delay() ;

WriteCmdLCD(CLR_DISP) ; // Configure LCD - Clear Display

LCD_L_Delay() ;

LCD_DATA = Temp_LCD_DATA ; // Restore Port Data (Useful if Port is shared, such as w/ LED)

}

//*********************************************

// _ ______________________________

// RS _>--<______________________________

// _____

// RW \_____________________________

// __________________

// E ____________/ \___

// _____________ ______

// DB _____________>---<______

//***********************************************

// Subroutine to

// Write Command to LCD module //

void WriteCmdLCD( unsigned char LCD_CMD) {

Temp_LCD_DATA = LCD_DATA ; // Save Port data to Temp buffer

Temp_CMD = (LCD_CMD & 0xF0)>>4 ; // Send high nibble to LCD bus LCD_DATA= (LCD_DATA & 0xfff0)|Temp_CMD ;

LCD_CMD_W_Timing () ;

Temp_CMD = LCD_CMD & 0x0F ; // Send low nibble to LCD bus

(13)

LCD_DATA= (LCD_DATA & 0xfff0)|Temp_CMD ; LCD_CMD_W_Timing () ;

LCD_DATA = Temp_LCD_DATA ; // Restore Port data

LCD_S_Delay() ; // Delay 100uS for

execution

}

//***********************************************

// Subroutine to

// Write Data to LCD module //

void WriteDataLCD( unsigned char LCD_CMD) {

Temp_LCD_DATA = LCD_DATA ; // Save Port data to Temp buffer

Temp_CMD = (LCD_CMD & 0xF0)>>4 ; // Send high nibble to LCD bus LCD_DATA= (LCD_DATA & 0xfff0)|Temp_CMD ;

LCD_DAT_W_Timing () ;

Temp_CMD = LCD_CMD & 0x0F ; // Send low nibble to LCD bus

LCD_DATA= (LCD_DATA & 0xfff0)|Temp_CMD ; LCD_DAT_W_Timing () ;

LCD_DATA = Temp_LCD_DATA ; // Restore Port data

LCD_S_Delay() ; // Delay 100uS for

execution

}

//***********************************************

// Subroutine to

// Write a character to LCD module

(14)

//

void putcLCD(unsigned char LCD_Char) {

WriteDataLCD(LCD_Char) ;

}

//***********************************************

// Subroutine to

// Write a command to LCD module // RS=0, R/W=0, E=H->L F(alling Edge)

void LCD_CMD_W_Timing( void ) // LCD Command writing timming

{

LCD_RS = 0 ; // Set for Command Input Nop();

LCD_RW = 0 ; Nop();

LCD_E = 1 ; Nop();

Nop();

Nop();

Nop();

LCD_E = 0 ; }

//***********************************************

// Subroutine to

// Write a command to LCD module // RS=1, R/W=0, E=H->L F(alling Edge)

void LCD_DAT_W_Timing( void ) // LCD Data writing timming {

LCD_RS = 1 ; // Set for Data Input Nop( );

LCD_RW = 0 ; Nop( );

(15)

LCD_E = 1 ; Nop( );

Nop( );

Nop( );

Nop( );

LCD_E = 0 ; }

//***********************************************

// Set Cursor position on LCD module // CurY = Line (0 or 1)

// CurX = Position ( 0 to 15) //

void setcurLCD(unsigned char CurX, unsigned char CurY) {

WriteCmdLCD( 0x80 + CurY * 0x40 + CurX) ; LCD_S_Delay() ;

}

//***********************************************

// Put a ROM string to LCD Module //

void putrsLCD( const char *Str ) {

while (1) {

Str_Temp = *Str ;

if (Str_Temp != 0x00 ) {

WriteDataLCD(Str_Temp) ; Str ++ ;

} else

return ; }

}

(16)

//***********************************************

// Put a RAM string to LCD Module //

void putsLCD( char *Str) {

while (1) {

Str_Temp = *Str ;

if (Str_Temp != 0x00 ) {

WriteDataLCD(Str_Temp) ; Str ++ ;

} else

return ; }

}

//***********************************************

// Put a byte in Hex format to LCD Module //

void puthexLCD(unsigned char HEX_Val) {

unsigned char Temp_HEX ;

Temp_HEX = (HEX_Val >> 4) & 0x0f ; // high nibble

if ( Temp_HEX > 9 )Temp_HEX += 0x37 ; // A~F

else Temp_HEX += 0x30 ; // 0~9

WriteDataLCD(Temp_HEX) ;

Temp_HEX = HEX_Val & 0x0f ; // low nibble if ( Temp_HEX > 9 )Temp_HEX += 0x37 ;

else Temp_HEX += 0x30 ;

(17)

WriteDataLCD(Temp_HEX) ; }

//***********************************************

// Put a byte in decimal format to LCD Module

// 0~99 Only. Uncomment the first 2 lines for hundreds

void put_Num_LCD( unsigned int The_Number ) {

unsigned char Temp_Char_100, Temp_Char_10, Temp_Char ;

Temp_Char_100 = The_Number /100 ; //取百位數的數字

putcLCD( Temp_Char_100 + '0' ) ; //轉換為 ASCII 編碼,'0'的編 碼加數字大小

Temp_Char_10 = (The_Number - Temp_Char_100*100) /10 ; //取 十位數的數字

putcLCD( Temp_Char_10 + '0' ) ;

Temp_Char = The_Number - ( Temp_Char_100*100 + Temp_Char_10 *

10 ) ; //取個位數的數字

putcLCD( 0x2e ) ;

putcLCD( Temp_Char + '0' ) ; }

// **********************************************

// Delay for atleast 10 ms

// **********************************************

void LCD_L_Delay(void) {

int L_Loop ;

for ( L_Loop = 0 ; L_Loop < 100 ; L_Loop ++ ) LCD_S_Delay( ) ;

}

// ***********************************************

// Delay for 100 us

// ***********************************************

(18)

void LCD_S_Delay(void) {

int S_Loop ; int Null_Var ;

for ( S_Loop = 0 ; S_Loop < 200 ; S_Loop ++ ) Null_Var += 1 ;

}

(19)

C30EVM_LCD.h:

void OpenLCD (void) ;

void WriteCmdLCD ( unsigned char ) ; void WriteDataLCD( unsigned char ) ; void putsLCD( char * ) ;

void putrsLCD( const char * ) ; void putcLCD( unsigned char ) ; void puthexLCD( unsigned char ) ; void put_Num_LCD( unsigned int ) ;

void setcurLCD( unsigned char , unsigned char ) ; // ( X-char, Y-line ) void LCD_CMD_W_Timing( void ) ;

void LCD_L_Delay( void ) ; void LCD_S_Delay( void ) ;

void LCD_DAT_W_Timing ( void ) ;

(20)

四 四 四

四、 、 、 、上 上 上課筆記 上 課筆記 課筆記 課筆記

(21)

五 五 五

五、 、 、 、實作 實作 實作結果 實作 結果 結果 結果

量測室內溫度 25.3 度

參考文獻

相關文件

▲關於升火建灶實務操作 小隊照片 記錄留念 (火煤棒生火爆米花).. ▲關於升火建灶實務操作

簡化內、外部作業流程,擴大本機關(單 位)或第一線機關(單位)服務措施的運 作彈性,提升服務效率。. (二)跨機關(單位)整合(50

單晶片電路接受到 A/D 轉換器的信號後,即將此數位信號由顥示器 顯示。此時單晶片 IC 並將此一 A/D 轉換器與指撥設定開關做比較,A/D 轉換器的信號高於設定值時,即由 OUT CONTROL

例如中央處理器、晶片、插卡等,這些電子元件在使用過程中,皆會產生熱

藝文及運動服務業、休閒服務業工作、製造業工作、批發業及其

FPPA 是 Filed Programmable Processor Array 的縮寫,簡 單的說:它就是一個可以平行處理的多核心單晶片微控器。與一般 微控器如 8051、pic,…

(二)受補助單位申請支付款項,應本誠信原則對所提出支用單據

 無線射頻識別 (Radio Frequency Identification, RFID) 系統近年來越來越普及,應用範圍如供