PIC Vietnam

Go Back   PIC Vietnam > Microchip PIC > dsPIC - Bộ điều khiển tín hiệu số 16-bit

Tài trợ cho PIC Vietnam
Trang chủ Đăng Kí Hỏi/Ðáp Thành Viên Lịch Bài Trong Ngày Vi điều khiển

dsPIC - Bộ điều khiển tín hiệu số 16-bit Theo dự kiến của Microchip, vào khoảng năm 2011 dsPIC sẽ có doanh số lớn hơn PIC

Trả lời
 
Ðiều Chỉnh Xếp Bài
Old 28-05-2008, 12:48 AM   #1
chukhivuitinh
Đệ tử 2 túi
 
Tham gia ngày: Jun 2005
Bài gửi: 27
:
Chương trình truyền AD lên Pc dùng dsPic30F4011 !! (bị lỗi jì ??)

Em gộp các prototype vào 1 file nhưng ko truyền UART được (lúc trước tách ra cũng ko đọc được ) dịch thì build succeeded bình thường,mấy bác giúp em cái :Yêu cầu chỉ là đọc AD của chân AN2 rùi lấy giá trị so trung bình rùi truyền lên PC thui .(có cần fải nối AN0 lên 5v ,và AN1 xuống mass ko (ADCHS ??? )
Code:
#include <p30f4011.h>

#include <uart.h>
#include <stdio.h>
#include <math.h>

_FWDT(WDT_OFF);                  
_FBORPOR(MCLR_EN & PWRT_OFF);    
_FGS(CODE_PROT_OFF);             

#define	FOSC			7372800
#define	PLL	   			1
#define	FCY	    		FOSC*PLL/4

#define SAMPLINGRATE    1800
#define SAMPCOUNT       (FCY/SAMPLINGRATE)+1	//dung cho TMR3 cho ADC

#define BAUDRATE 		9600   
#define U1BRG    		FCY/16/BAUDRATE -1		//dung cho UART

#define AN0 			0						//khai bao adc_buf
#define adc_read(pin) 	adc_buf[pin] 			

//==== Cac prototype ====
void adc_init();
void adc_start();
void adc_stop();

void uart1_open();
void uart1_close();
void uart1_puts(char[]);

void PrintSignedInteger(int x, void (*printer)(char[]));

//==== cac bien ====
unsigned int adc_buf[16];

//==== ham main ===
int main()
{
	float tb;
	
	adc_init();
	adc_start();

	uart1_open();
		
	while(1)
	{						
			float trungbinh_AN0()
				{
					return (((float)adc_read(AN0) / 65500.0*5.)-2.5)/0.002; // gia tri so voi trung binh /don vi
				}
			tb = trungbinh_AN0();
			
			PrintSignedInteger(tb, &uart1_puts); // Send result to uart
			uart1_puts("\n\r");
	}
	
	uart1_close();
	return 0;
}

//==== ADC ====
void adc_init()
{
    adc_stop();									// reset adc 
	
        ADCON2bits.SMPI = 3;    				// SMPI gom 4bit ,tuong ung uC ngat khi 1->16 lan lay mau 
    	ADCON2bits.CHPS = 0;    				// CHPS = 00 chon kenh 0 de chuyen doi
    											// CHPS = 01 chon kenh 0 va kenh 1 de chuyen doi
												// CHPS = 1x chon tat ca cac kenh de chuyen doi
    	ADCON1bits.SIMSAM = 0;  				// SIMSAM = 0 lay mau tung kenh 1 cach tuan tu
												// SIMSAM = 1 lay mau 4 kenh (0,1,2,3) 1 cach dong thoi
    	ADCON2bits.BUFM = 0;  					// BUFM = 0 lay 1 lan 16 bit 
												// BUFM = 1 lay 2 lan ,moi lan 8 bit 			
   		ADCON2bits.BUFS = 0;
		ADCON2bits.ALTS = 0;    				// ALTS = 0 luon luon su dung MUX A lam bo don kenh
												// ALTS = 1 ban dau dung Mux A ,sau do xen ke MuxB va Mux A lam bo don kenh
    
    // MUX A Input Select
    	ADCHSbits.CH0SA = 2;    				// CH0SA = 0 chon nguon duong cua kenh A la AN0
												// CH0SA = x chon nguon duong cua kenh A la ANx
		ADCHSbits.CH0NA = 0;   					// CH0NA = 0 chon nguon am cua kenh A la Vref-
												// CH0NA = 1 chon nguon am cua kenh A la AN1
    	ADCON2bits.CSCNA = 1;   				// 1 quet ngo vao 
												// 0 ko quet
    	ADCSSL = 0b0000000000111100;   			// Scan AN2..AN5 quet chan nao thi cho chan do len 1
												// adc_buf tinh tu bit2=>5 ,vay adc_buf[0] = quet chan AN2
    
	// chon nguon am duong cho cac kenh 1,2,3
    	ADCHSbits.CH123SA = 0;  
    	ADCHSbits.CH123NA = 0;  
    
    // MUX B Input Select
    	ADCHSbits.CH123SB = 0;  
    	ADCHSbits.CH123NB = 0;  
    
    
    // SPECIFIC BITS
    	ADCON1bits.FORM = 0b00;  				// output la integer
    	ADCON1bits.SSRC = 0b010;     			// chon bo dem de chuyen doi (3bit) => dung Timer 3 de dem 
    	ADCON1bits.ASAM = 1;      				// 1 : tu dong tiep tuc lay mau khi chuyen doi xong ,bit SAMP tu dong set
												// 0 : chuyen doi xong ,doi bit SAMP set thi moi tiep tuc lay mau
    	ADCON2bits.VCFG = 0b000; 				// 3bit : chon nguon tham khao => dung AVdd va AVss
   		ADCON3bits.SAMC = 0b11111;				// dung 31 Tad cho lay mau
		ADCON3bits.ADRC = 0;					// dung clock he thong
		ADCON3bits.ADCS = 0b011110;    			// chon xung chuyen doi (6bit tuong ung 1->32xTcy)
    	ADPCFG = 0xFF00;         				// AN0..AN7 la analog
												// 0 : ngo vao la analog
												// 1 : ngo vao la digital
    	TRISB = 0b11111111;      				// Port B la input
    
    // INITIALIZE TIMER3 (dung cho bo dem ADC)
    	TMR3 = 0x0000;
    	PR3 = SAMPCOUNT;
    	IFS0bits.ADIF = 0;       				// Clear the A/D interrupt flag bit
    	IEC0bits.ADIE = 1;       				// Set the A/D interrupt enable bit 
}

void adc_start()
{
    ADCON1bits.ADON = 1;

    T3CONbits.TON = 1;	
}

void adc_stop()
{
    ADCON1bits.ADON = 0;

    T3CONbits.TON = 0;
}

//==== UART1 ====

void uart1_close()
{
	CloseUART1();								// co san trong uart.h cua microchip	
}

void uart1_open()
{
	unsigned int baudvalue;   
	unsigned int U1MODEvalue;
	unsigned int U1STAvalue; 

	uart1_close();
	ConfigIntUART1(UART_RX_INT_DIS & UART_TX_INT_DIS);
	baudvalue = U1BRG;
    U1MODEvalue = 0x8000;
				/*UART_EN & UART_IDLE_STOP & UART_RX_TX &
                  UART_DIS_WAKE & UART_DIS_LOOPBACK  &
                  UART_DIS_ABAUD & UART_NO_PAR_8BIT  &
                  UART_1STOPBIT;*/
    U1STAvalue  = 0x0400;
				/*UART_INT_TX_BUF_EMPTY  &  
                  UART_TX_PIN_NORMAL &
                  UART_TX_ENABLE & UART_INT_RX_3_4_FUL &
                  UART_ADR_DETECT_DIS &
                  UART_RX_OVERRUN_CLEAR;*/               
	OpenUART1(U1MODEvalue, U1STAvalue, baudvalue);
}

void uart1_puts(char string[])
{
	putsUART1 ((unsigned int *)string);  			// lay gia tri de gui di 
	while (BusyUART1());
}

//==== ham truyen len pc ====
void PrintSignedInteger(int x, void (*printer)(char[]))
{
	static char tmpChar[2] = "0";
	unsigned int radix, i, converted;
	char emptyChar = ' ';
	
	if (x < 0)
	{
		printer("-");
		x*=-1;
	}
	else if (x == 0)
	{
		printer("0");
		return;	
	}
	converted = (unsigned int) x;
	

	// auto-align on 16bit size (655.. = 5 positions)
	for (radix=10000, i=0; i < 5; radix/=10, i++)
	{
		if (converted > radix-1) 
		{
			tmpChar[0] =  '0' + (converted/radix);
			printer(tmpChar);
			converted = converted % radix;
			emptyChar = '0';
		} 
		else if (emptyChar == '0') 
		{
			printer("0");
		}
	}
}
Em đọc bằng hyper terminal thì trắng trơn hà ,dùng Labview (dùng cái exam basic serial write and read .vi) thì báo lỗi này :
Trích:
VISA: (Hex 0xBFFF0072) The resource is valid, but VISA cannot currently access it.
,bác nào xài lapview thì chỉ em lun ^_^

thay đổi nội dung bởi: chukhivuitinh, 28-05-2008 lúc 12:58 AM.
chukhivuitinh vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 28-05-2008, 02:46 AM   #2
namqn
Trưởng lão PIC bang
 
Tham gia ngày: Feb 2006
Nơi Cư Ngụ: Tp. HCM, Việt Nam
Bài gửi: 3,025
:
Send a message via Yahoo to namqn
Không rõ bạn đọc tutorial 5 cho dsPIC của tôi chưa. Ví dụ 5-2 của tutorial đó đọc ngõ vào AN0 sau mỗi giây, và truyền về máy tính qua cổng RS-232.

Thân,
__________________
Biển học mênh mông, sức người có hạn.

Đang gặp vấn đề cần được giúp đỡ? Hãy dành ra vài phút đọc luồng sau:
http://www.picvietnam.com/forum/showthread.php?t=1263
namqn vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 28-05-2008, 04:11 PM   #3
chukhivuitinh
Đệ tử 2 túi
 
Tham gia ngày: Jun 2005
Bài gửi: 27
:
em đã đọc rồi và đã thực hành chạy được rồi ,em có review lại trong bài tutorial đó của anh rồi .Còn chương trình này em tự viết lại theo prototype có sẵn ,anh đọc chương trình thì thấy thật sự em ko chỉ đọc AN2 mà đọc lun AN3,AN4,AN5 (trong phần khai báo adc) ,em đọc từ ADCBUF0->3 lên,nhưng ko thấy nó xuất kết quả jì cả ,nên em mới lên hỏi các anh .
Nhờ mấy anh giúp đỡ em nhỏ cái hen ^_^
P/S : Em gữi file nó lên lun
File Kèm Theo
File Type: rar test.rar (48.9 KB, 9 lần tải)

thay đổi nội dung bởi: chukhivuitinh, 28-05-2008 lúc 04:47 PM.
chukhivuitinh vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 28-05-2008, 05:17 PM   #4
namqn
Trưởng lão PIC bang
 
Tham gia ngày: Feb 2006
Nơi Cư Ngụ: Tp. HCM, Việt Nam
Bài gửi: 3,025
:
Send a message via Yahoo to namqn
Ý của tôi là bạn bắt đầu với một chương trình thật đơn giản, đã chạy tốt. Thêm dần những tính năng mà bạn cần vào, để có thể kiểm tra ở mỗi bước rằng những gì bạn thêm vào đều làm việc tốt.

Bạn có thể dùng code của tôi hay của ai đó làm điểm khởi đầu, nhưng không nên thay đổi hàng loạt hay viết mới hoàn toàn, vì sẽ rất khó xác định lỗi nằm ở đâu. Cách làm việc tốt hơn là bạn thử nghiệm những chức năng mới, nếu bạn gặp khó khăn thì post đoạn code trước và sau khi thay đổi.

Việc dò lại toàn bộ chương trình của bạn để tìm lỗi khá tốn thời gian, và không may là lúc này tôi khá bận.

Thân,
__________________
Biển học mênh mông, sức người có hạn.

Đang gặp vấn đề cần được giúp đỡ? Hãy dành ra vài phút đọc luồng sau:
http://www.picvietnam.com/forum/showthread.php?t=1263
namqn vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 28-05-2008, 05:52 PM   #5
chukhivuitinh
Đệ tử 2 túi
 
Tham gia ngày: Jun 2005
Bài gửi: 27
:
Em xin tách ra cho dễ nhìn nha ^_^ :
ADC:
Code:
#define SAMPLINGRATE    1800
#define SAMPCOUNT       (FCY/SAMPLINGRATE)+1	//dung cho TMR3 cho ADC

#define adc_read(pin) 	adc_buf[pin]

unsigned int adc_buf[16];
volatile unsigned int* ADC16Ptr = &ADCBUF0; 		//Pointer to ADC register buffer, 
unsigned int adc_filter_buffer[4][6] = { {0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0} };
unsigned int current_buf = 1;

//==== ADC ====
void adc_init()
{
    adc_stop();					// reset adc 
	//====ADCON1====
	ADCON1bits.SIMSAM = 0;  		// SIMSAM = 0 lay mau tung kenh 1 cach tuan tu
							// SIMSAM = 1 lay mau 4 kenh (0,1,2,3) 1 cach dong thoi
        ADCON1bits.FORM = 0b00;  		// output la integer
    	ADCON1bits.SSRC = 0b010;     	// chon bo dem de chuyen doi (3bit) => dung Timer 3 de dem 
    	ADCON1bits.ASAM = 1;      		// 1 : tu dong tiep tuc lay mau khi chuyen doi xong ,bit SAMP tu dong set
							// 0 : chuyen doi xong ,doi bit SAMP set thi moi tiep tuc lay mau
	//====ADCON2====
	ADCON2bits.SMPI = 5;    		// SMPI gom 4bit ,tuong ung uC ngat khi 1->16 lan lay mau 
    	ADCON2bits.CHPS = 0;    		// CHPS = 00 chon kenh 0 de chuyen doi
    							// CHPS = 01 chon kenh 0 va kenh 1 de chuyen doi
							// CHPS = 1x chon tat ca cac kenh de chuyen doi
    	ADCON2bits.BUFM = 0;  		// BUFM = 0 lay 1 lan 16 bit 
							// BUFM = 1 lay 2 lan ,moi lan 8 bit 			
   	ADCON2bits.BUFS = 0;
	ADCON2bits.ALTS = 0;    		// ALTS = 0 luon luon su dung MUX A lam bo don kenh
							// ALTS = 1 ban dau dung Mux A ,sau do xen ke MuxB va Mux A lam bo don kenh
    	ADCON2bits.CSCNA = 1;   		// 1 quet ngo vao 
							// 0 ko quet
    	ADCON2bits.VCFG = 0b000; 		// 3bit : chon nguon tham khao => dung AVdd va AVss
	//====ADCON3====
	ADCON3bits.SAMC = 0b11111;	// dung 31 Tad cho lay mau
	ADCON3bits.ADRC = 0;			// dung clock he thong
	ADCON3bits.ADCS = 0b011111;    	// chon xung chuyen doi (6bit tuong ung 1->32xTcy)
	//====ADCHS====
    	ADCHSbits.CH0SA = 2;    		// CH0SA = 0 chon nguon duong cua kenh A la AN0
							// CH0SA = x chon nguon duong cua kenh A la ANx
	ADCHSbits.CH0NA = 0;   		// CH0NA = 0 chon nguon am cua kenh A la Vref-
							// CH0NA = 1 chon nguon am cua kenh A la AN1
    				// chon nguon am duong cho cac kenh 1,2,3
    	ADCHSbits.CH123SA = 0;  
    	ADCHSbits.CH123NA = 0;  
    
    				// MUX B Input Select
    	ADCHSbits.CH123SB = 0;  
    	ADCHSbits.CH123NB = 0;  
    //====ADCSSL====
	ADCSSL = 0b0000000000111100;   	// Scan AN2..AN5 quet chan nao thi cho chan do len 1
							// adc_buf tinh tu bit2=>5 ,vay adc_buf[0] = quet chan AN2
	//====ADPCFG====
    	ADPCFG = 0xFF00;         		// AN0..AN7 la analog
							// 0 : ngo vao la analog
							// 1 : ngo vao la digital
    //==== khai bao PORTB ====	
	TRISB = 0b11111111;      		// Port B la input
    
    // INITIALIZE TIMER3 (dung cho bo dem ADC)
    	TMR3 = 0x0000;
    	PR3 = SAMPCOUNT;
    	IFS0bits.ADIF = 0;       			// Clear the A/D interrupt flag bit
    	IEC0bits.ADIE = 1;       			// Set the A/D interrupt enable bit 
}

void adc_start()
{
    ADCON1bits.ADON = 1;

    T3CONbits.TON = 1;	
}

void adc_stop()
{
    ADCON1bits.ADON = 0;

    T3CONbits.TON = 0;
}

void __attribute__((__interrupt__)) _ADCInterrupt(void)
{
	unsigned int i;
	
	for (i=0; i < 6; i++)
  		adc_filter_buffer[current_buf][i] = ADC16Ptr[i];

    for (i=0; i < 6; i++)
     	adc_buf[i] = (adc_filter_buffer[current_buf][i]/6 + 
     	              adc_filter_buffer[(current_buf+1)%4][i]/6 +
     	              adc_filter_buffer[(current_buf+2)%4][i]/3 +
     	              adc_filter_buffer[(current_buf+3)%4][i]/3);
	current_buf = (current_buf+1) % 4;
	
	IFS0bits.ADIF = 0;
}
típ UART :
Code:
#define BAUDRATE 		9600   
#define U1BRG    		FCY/16/BAUDRATE -1		//dung cho UART

//==== UART1 ====

void uart1_close()
{
	CloseUART1();					// co san trong uart.h cua microchip	
}

void uart1_open()
{
	unsigned int baudvalue;   
	unsigned int U1MODEvalue;
	unsigned int U1STAvalue; 

	uart1_close();
	ConfigIntUART1(UART_RX_INT_DIS & UART_TX_INT_DIS);
	baudvalue = U1BRG;

    U1MODEvalue = 0x8000;
				
    U1STAvalue  = 0x0400;
				               
	OpenUART1(U1MODEvalue, U1STAvalue, baudvalue);
}

void uart1_puts(char string[])
{
	putsUART1 ((unsigned int *)string);  			// lay gia tri de gui di 
	while (BusyUART1());
}
hàm main :
Code:
//==== ham main ===
int main()
{
	float tb;
	
	adc_init();
	adc_start();

	uart1_open();
		
	while(1)
	{						
		float trungbinh_AN0()
			{
				return (((float)adc_read(AN0) / 65500.0*5.)-2.5)/0.002; // gia tri so voi trung binh /don vi
			}
			tb = trungbinh_AN0();
			
			PrintSignedInteger(tb, &uart1_puts); // Send result to uart
			uart1_puts("\n\r");
	}
	
	uart1_close();
	return 0;
}

void PrintSignedInteger(int x, void (*printer)(char[]))
{
	static char tmpChar[2] = "0";
	unsigned int radix, i, converted;
	char emptyChar = ' ';
	
	if (x < 0)
	{
		printer("-");
		x*=-1;
	}
	else if (x == 0)
	{
		printer("0");
		return;	
	}
	converted = (unsigned int) x;
	

	// auto-align on 16bit size (655.. = 5 positions)
	for (radix=10000, i=0; i < 5; radix/=10, i++)
	{
		if (converted > radix-1) 
		{
			tmpChar[0] =  '0' + (converted/radix);
			printer(tmpChar);
			converted = converted % radix;
			emptyChar = '0';
		} 
		else if (emptyChar == '0') 
		{
			printer("0");
		}
	}
}
Mấy bác giúp em với nha ,em vẫn chưa tìm được lỗi ở đâu ,ban đầu nghĩ ở chỗ ngắt AD ,rùi chỗ lấy adc_buf ,rùi hàm truyền lên pc ,nhưng đều ko fải ,hihixhix

thay đổi nội dung bởi: chukhivuitinh, 28-05-2008 lúc 06:09 PM.
chukhivuitinh vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 28-05-2008, 06:49 PM   #6
chukhivuitinh
Đệ tử 2 túi
 
Tham gia ngày: Jun 2005
Bài gửi: 27
:
Em chưa hiểu chỗ thanh ghi ADCHS :
Code:
    	ADCHSbits.CH0SA = 2;    	// CH0SA = 0 chon nguon duong cua kenh A la AN0
						// CH0SA = x chon nguon duong cua kenh A la ANx
	ADCHSbits.CH0NA = 0;          // CH0NA = 0 chon nguon am cua kenh A la Vref-
						// CH0NA = 1 chon nguon am cua kenh A la AN1
Em đọc AD từ 4 chân AN2 ,AN3 ,AN4 .... ,vậy nếu như trên thì nó lấy nguồn dương cho kênh A là AN2 thui ,vậy các chân kia ????

Trong khi đó em đã chọn AVdd và AVss làm nguồn tham khảo ở thanh ghi ADCON2 rùi ,vậy có cần fải thêm ,lấy nguồn dương cho kênh A là AN0 ,nguồn âm là AN1 rồi nối 2 chân này vào nguồn ko ???
chukhivuitinh vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 29-05-2008, 12:52 PM   #7
chukhivuitinh
Đệ tử 2 túi
 
Tham gia ngày: Jun 2005
Bài gửi: 27
:
Em dùng prototype có sẵn nên vẫn chưa hiểu 1 số chỗ :
_Trong phần adc ,phần ngắt :
Code:
// phần khai báo biến bên trên 
unsigned int adc_buf[16];
volatile unsigned int* ADC16Ptr = &ADCBUF0; //Pointer to ADC register buffer, 
unsigned int adc_filter_buffer[4][6] = { {0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0},{0,0,0,0,0,0} };
unsigned int current_buf = 1; 


void __attribute__((__interrupt__)) _ADCInterrupt(void)
{
	unsigned int i;
        for (i=0; i < 6; i++)
  		adc_filter_buffer[current_buf][i] = ADC16Ptr[i];
        for (i=0; i < 6; i++)
     	        adc_buf[i] = (adc_filter_buffer[current_buf][i]/6 + 
     	              adc_filter_buffer[(current_buf+1)%4][i]/6 +
     	              adc_filter_buffer[(current_buf+2)%4][i]/3 +
     	              adc_filter_buffer[(current_buf+3)%4][i]/3);
	current_buf = (current_buf+1) % 4;
	IFS0bits.ADIF = 0;
}
_trong hàm PrintSignedInteger ,có đoạn :
Code:
// auto-align on 16bit size (655.. = 5 positions)
	for (radix=10000, i=0; i < 5; radix/=10, i++)
	{
		if (converted > radix-1) 
		{
			tmpChar[0] =  '0' + (converted/radix);
			printer(tmpChar);
			converted = converted % radix;
			emptyChar = '0';
		} 
		else if (emptyChar == '0') 
		{
			printer("0");
		}
	}
a giúp em phân tích với ^_^

PS : em là dân cơ khí nhưng vì 1 lí do bắt buộc em phải làm phần điều khiển nên thật sự em chỉ là ăn sổi nhưng em chắc chắn 1 điều là những cái em hỏi em đã đầu tư suy nghĩ ,chứ ko fải cứ bị trục trặc là xách lên hỏi ,nên mong các bác thông cảm nếu có những câu hỏi hơi ngớ ngẩn .

thay đổi nội dung bởi: chukhivuitinh, 29-05-2008 lúc 01:03 PM.
chukhivuitinh vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Trả lời


Quyền Sử Dụng Ở Diễn Ðàn
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is Mở
Smilies đang Mở
[IMG] đang Mở
HTML đang Tắt

Chuyển đến


Múi giờ GMT. Hiện tại là 09:02 AM.


Được sáng lập bởi Đoàn Hiệp
Powered by vBulletin®
Page copy protected against web site content infringement by Copyscape
Copyright © PIC Vietnam