PDA

View Full Version : Chơi xếp hình trên Tivi với vi điều khiển PIC


tuan_vip
09-01-2010, 08:04 PM
Lang thang trên mạng em tìm dc đề tài khá hay

http://www.rickard.gunee.com/projects/video/pic/howto.php

Code chương trình toàn viết bằng asm em nhìn không hiểu dc.
AE có thể giúp em lập trình 1 đoạn code đơn giản đưa 1 chữ "KHOA DIEN" lên màn hình được không. Em dùng vi điều khiển PIC 16f84 nhé, đây là sơ đồ mạch ạ

http://www.rickard.gunee.com/projects/video/pic/schematic_big.png

EM cảm ơn nhiều.

Y!m : anhtuan_ent

laiquangtuyen
09-01-2010, 10:20 PM
http://www.exploringpic32.com/Adv.html
Giống ở đây!

tuan_vip
10-01-2010, 10:08 AM
http://www.exploringpic32.com/Adv.html
Giống ở đây!

Bạn có thể giúp mình 1 đoạn code đơn giản bằng C đưa ra 1 chữ trên miàn hình được không. Các code của họ toàn viết bằng asm nên mình ko hiểu dc >"<.

Mong mọi người giúp đỡ

laiquangtuyen
10-01-2010, 12:51 PM
Bạn có thể giúp mình 1 đoạn code đơn giản bằng C đưa ra 1 chữ trên miàn hình được không. Các code của họ toàn viết bằng asm nên mình ko hiểu dc >"<.

Mong mọi người giúp đỡ
ví dụ của code đưa ra màn hình và các hàm khác.
void initVideo( void)
{
// 1. init the SPI1
// select framed slave mode to synch SPI with OC3
SpiChnOpen( 1, SPICON_ON | SPICON_MSTEN //| SPICON_MODE8
| SPICON_FRMEN | SPICON_FRMSYNC | SPICON_FRMPOL
, PIX_T);

// 2. make SS1(RB2) a digital input, RG0 VSYNCH output
AD1PCFGSET = 0x0004;
_TRISG0=0;
_LATG0=1;

// 3. init OC3 in single pulse, continuous mode
OpenOC3( OC_ON | OC_TIMER3_SRC | OC_CONTINUE_PULSE,
0, HSYNC_T);

// 4. Timer3 on, prescaler 1:1, internal clock, period
OpenTimer3( T3_ON | T3_PS_1_1 | T3_SOURCE_INT, LINE_T-1);

// 5. init the vertical sync state machine
VState = SV_PREEQ;
VCount = 1;

// 6. init the active and hidden screens pointers
VA = VMap1;
#ifdef DOUBLE_BUFFER
VH = VMap2;
#else
VH = VA;
#endif

// 7. DMA 1 configuration back porch extension
DmaChnOpen( 1, 1, DMA_OPEN_DEFAULT);
DmaChnSetEventControl( 1, DMA_EV_START_IRQ_EN |
DMA_EV_START_IRQ(_SPI1_TX_IRQ));
DmaChnSetTxfer( 1, (void*)zero, (void *)&SPI1BUF,
4, 1, 1);

// 8. DMA 0 configuration image serialization
DmaChnOpen( 0, 0, DMA_OPEN_DEFAULT);
DmaChnSetEventControl( 0, DMA_EV_START_IRQ_EN |
DMA_EV_START_IRQ(_SPI1_TX_IRQ));
DmaChnSetTxfer( 0, (void*)VPtr, (void *)&SPI1BUF,
HRES/8, 1, 1);
// chain DMA0 to completion of DMA1 transfer
DmaChnSetControlFlags( 0, DMA_CTL_CHAIN_EN | DMA_CTL_CHAIN_DIR);

// 9. Enable Timer3 Interrupts
// set the priority level 7 to use shadow register set
mT3SetIntPriority( 7);
mT3IntEnable( 1);

} // initVideo


void clearScreen( void)
{ // fill with zeros the Active Video array
memset( VA, 0, VRES*( HRES/8));

// reset text cursor position
cx = cy = 0;

} //clearScreen


void clearHScreen( void)
{ // fill with zeros the Hidden Video array
memset( VH, 0, VRES*( HRES/8));

// reset text cursor position
cx = cy = 0;

} //clearHScreen


void * getAVideo( void)
{ // return a pointer to Active Video array
return VA;
} // getAVideo


void haltVideo( void)
{
T3CONbits.TON = 0; // turn off the vertical state machine
} //haltVideo


void swapV( void)
{
char * V;

if ( VState == SV_LINE)
while ( VCount != 1); // wait end of the frame
V = VA; VA = VH; VH = V; // swap the pointers
VPtr = VA;
} // swapV


void singleV( void)
{ // make all functions work on a single image buffer
VA = VMap1;
VH = VA;
} // singleV


void plot( unsigned x, unsigned y)
{
if ((x<HRES) && (y<VRES) )
VH[ ((VRES-1-y)*(HRES/8))+(x>>3)] |=
( 0x80>>(x&0x7));
} // plot


#define abs( a) (((a)> 0) ? (a) : -(a))

void line( short x0, short y0, short x1, short y1)
{
short steep, t ;
short deltax, deltay, error;
short x, y;
short ystep;

// simple clipping
if (( x0 < 0) || (x0>=HRES))
return;
if (( x1 < 0) || (x1>=HRES))
return;
if (( y0 < 0) || (y0>=VRES))
return;
if (( y1 < 0) || (y1>=VRES))
return;

steep = ( abs(y1 - y0) > abs(x1 - x0));

if ( steep )
{ // swap x and y
t = x0; x0 = y0; y0 = t;
t = x1; x1 = y1; y1 = t;
}
if (x0 > x1)
{ // swap ends
t = x0; x0 = x1; x1 = t;
t = y0; y0 = y1; y1 = t;
}

deltax = x1 - x0;
deltay = abs(y1 - y0);
error = 0;
y = y0;

if (y0 < y1) ystep = 1; else ystep = -1;
for (x = x0; x < x1; x++)
{
if ( steep) plot(y,x); else plot(x,y);
error += deltay;
if ( (error<<1) >= deltax)
{
y += ystep;
error -= deltax;
} // if
} // for
} // line

int cx, cy;

void putcV( char a)
{
int i, j;
char *p;
const char *pf;

// 0. check for backspace
if ( a == 0x8)
{
if ( cx > 0)
cx--;
return;
}

// 1. check if char in range
if ( a < F_OFFS)
return;
if ( a >= F_OFFS+F_SIZE)
return;

// 2. check page boundaries and wrap or scroll as necessary
if ( cx >= HRES/8) // wrap around x
{
cx = 0;
cy++;
}
if ( cy >= VRES/8) // scroll up y
{
char *pd = VH;
char *ps = pd + (HRES/8)*8;
for( i=0; i<(HRES/8)*(VRES-8); i++)
*pd++ = *ps++;
for( i=0; i<(HRES/8)*8; i++)
*pd++ = 0;
// keep cursor within boundary
cy = VRES/8-1;
}
// 3. set pointer to word in the video map
p = &VH[ cy * 8 * HRES/8 + cx];
// set pointer to first row of the character in font array
pf = &Font8x8[ (a-F_OFFS) << 3];

// 4. copy one by one each line of the character on screen
for ( i=0; i<8; i++)
{
*p = *pf++;

// point to next row
p += HRES/8;
} // for

// 5. advance cursor position
cx++;
} // putcV


void putsV( char *s)
{
while (*s)
putcV( *s++);
// advance to next line
cx=0; cy++;
} // putsV

Mình nghiên cứu cũng lâu nhưng chưa có mặn mà lắm, vì nó còn nhiều thứ dính vô mà chưa có hiểu hết.

tuan_vip
10-01-2010, 04:56 PM
ĐOạn code trên mình biên dịch sang hex rồi nạp thử có chạy luôn được không hả bạn. Hiện mình đang cần làm bài tập đưa ra màn hình chữ "KHOA DIEN" sử dụng PIC6F84. Về phần mạch mình đã làm xong và hoạt động tốt khi mình nạp thử nghiệm code trên trang web.

Mình rất mong được sự giúp đỡ của các bạn, nếu có dc file hex để nạp thử mình xin cảm ơn lắm lắm và hậu tạ

laiquangtuyen
10-01-2010, 06:41 PM
ĐOạn code trên mình biên dịch sang hex rồi nạp thử có chạy luôn được không hả bạn. Hiện mình đang cần làm bài tập đưa ra màn hình chữ "KHOA DIEN" sử dụng PIC6F84. Về phần mạch mình đã làm xong và hoạt động tốt khi mình nạp thử nghiệm code trên trang web.

Mình rất mong được sự giúp đỡ của các bạn, nếu có dc file hex để nạp thử mình xin cảm ơn lắm lắm và hậu tạ
không chạy được, vì mình chỉ trích một phần nhỏ xíu trong cái project ra mà bạn. Còn bạn muốn ntn thì bạn cần hiểu rõ ràng tường tận vấn đề sau đó mới chuyển đổi source sang C được. Mình cũng đang tìm hiểu chứ chưa rõ lắm về vấn đề này nữa!

tuan_vip
11-01-2010, 03:54 PM
Thì vấn đề mình đưa ra là muốn lập trình cho PIC6f84 để đưa ra màn hình tivi một chữ bất kì đó. Mạch điện cũng có ở trên mình lắp xong rồi, còn khổ sở phần lập tình nữa. Mong được mọi người giúp đỡ

vinhtdh
04-05-2013, 02:17 AM
ví dụ của code đưa ra màn hình và các hàm khác.
void initVideo( void)
{
// 1. init the SPI1
// select framed slave mode to synch SPI with OC3
SpiChnOpen( 1, SPICON_ON | SPICON_MSTEN //| SPICON_MODE8
| SPICON_FRMEN | SPICON_FRMSYNC | SPICON_FRMPOL
, PIX_T);

// 2. make SS1(RB2) a digital input, RG0 VSYNCH output
AD1PCFGSET = 0x0004;
_TRISG0=0;
_LATG0=1;

// 3. init OC3 in single pulse, continuous mode
OpenOC3( OC_ON | OC_TIMER3_SRC | OC_CONTINUE_PULSE,
0, HSYNC_T);

// 4. Timer3 on, prescaler 1:1, internal clock, period
OpenTimer3( T3_ON | T3_PS_1_1 | T3_SOURCE_INT, LINE_T-1);

// 5. init the vertical sync state machine
VState = SV_PREEQ;
VCount = 1;

// 6. init the active and hidden screens pointers
VA = VMap1;
#ifdef DOUBLE_BUFFER
VH = VMap2;
#else
VH = VA;
#endif

// 7. DMA 1 configuration back porch extension
DmaChnOpen( 1, 1, DMA_OPEN_DEFAULT);
DmaChnSetEventControl( 1, DMA_EV_START_IRQ_EN |
DMA_EV_START_IRQ(_SPI1_TX_IRQ));
DmaChnSetTxfer( 1, (void*)zero, (void *)&SPI1BUF,
4, 1, 1);

// 8. DMA 0 configuration image serialization
DmaChnOpen( 0, 0, DMA_OPEN_DEFAULT);
DmaChnSetEventControl( 0, DMA_EV_START_IRQ_EN |
DMA_EV_START_IRQ(_SPI1_TX_IRQ));
DmaChnSetTxfer( 0, (void*)VPtr, (void *)&SPI1BUF,
HRES/8, 1, 1);
// chain DMA0 to completion of DMA1 transfer
DmaChnSetControlFlags( 0, DMA_CTL_CHAIN_EN | DMA_CTL_CHAIN_DIR);

// 9. Enable Timer3 Interrupts
// set the priority level 7 to use shadow register set
mT3SetIntPriority( 7);
mT3IntEnable( 1);

} // initVideo


void clearScreen( void)
{ // fill with zeros the Active Video array
memset( VA, 0, VRES*( HRES/8));

// reset text cursor position
cx = cy = 0;

} //clearScreen


void clearHScreen( void)
{ // fill with zeros the Hidden Video array
memset( VH, 0, VRES*( HRES/8));

// reset text cursor position
cx = cy = 0;

} //clearHScreen


void * getAVideo( void)
{ // return a pointer to Active Video array
return VA;
} // getAVideo


void haltVideo( void)
{
T3CONbits.TON = 0; // turn off the vertical state machine
} //haltVideo


void swapV( void)
{
char * V;

if ( VState == SV_LINE)
while ( VCount != 1); // wait end of the frame
V = VA; VA = VH; VH = V; // swap the pointers
VPtr = VA;
} // swapV


void singleV( void)
{ // make all functions work on a single image buffer
VA = VMap1;
VH = VA;
} // singleV


void plot( unsigned x, unsigned y)
{
if ((x<HRES) && (y<VRES) )
VH[ ((VRES-1-y)*(HRES/8))+(x>>3)] |=
( 0x80>>(x&0x7));
} // plot


#define abs( a) (((a)> 0) ? (a) : -(a))

void line( short x0, short y0, short x1, short y1)
{
short steep, t ;
short deltax, deltay, error;
short x, y;
short ystep;

// simple clipping
if (( x0 < 0) || (x0>=HRES))
return;
if (( x1 < 0) || (x1>=HRES))
return;
if (( y0 < 0) || (y0>=VRES))
return;
if (( y1 < 0) || (y1>=VRES))
return;

steep = ( abs(y1 - y0) > abs(x1 - x0));

if ( steep )
{ // swap x and y
t = x0; x0 = y0; y0 = t;
t = x1; x1 = y1; y1 = t;
}
if (x0 > x1)
{ // swap ends
t = x0; x0 = x1; x1 = t;
t = y0; y0 = y1; y1 = t;
}

deltax = x1 - x0;
deltay = abs(y1 - y0);
error = 0;
y = y0;

if (y0 < y1) ystep = 1; else ystep = -1;
for (x = x0; x < x1; x++)
{
if ( steep) plot(y,x); else plot(x,y);
error += deltay;
if ( (error<<1) >= deltax)
{
y += ystep;
error -= deltax;
} // if
} // for
} // line

int cx, cy;

void putcV( char a)
{
int i, j;
char *p;
const char *pf;

// 0. check for backspace
if ( a == 0x8)
{
if ( cx > 0)
cx--;
return;
}

// 1. check if char in range
if ( a < F_OFFS)
return;
if ( a >= F_OFFS+F_SIZE)
return;

// 2. check page boundaries and wrap or scroll as necessary
if ( cx >= HRES/8) // wrap around x
{
cx = 0;
cy++;
}
if ( cy >= VRES/8) // scroll up y
{
char *pd = VH;
char *ps = pd + (HRES/8)*8;
for( i=0; i<(HRES/8)*(VRES-8); i++)
*pd++ = *ps++;
for( i=0; i<(HRES/8)*8; i++)
*pd++ = 0;
// keep cursor within boundary
cy = VRES/8-1;
}
// 3. set pointer to word in the video map
p = &VH[ cy * 8 * HRES/8 + cx];
// set pointer to first row of the character in font array
pf = &Font8x8[ (a-F_OFFS) << 3];

// 4. copy one by one each line of the character on screen
for ( i=0; i<8; i++)
{
*p = *pf++;

// point to next row
p += HRES/8;
} // for

// 5. advance cursor position
cx++;
} // putcV


void putsV( char *s)
{
while (*s)
putcV( *s++);
// advance to next line
cx=0; cy++;
} // putsV

Mình nghiên cứu cũng lâu nhưng chưa có mặn mà lắm, vì nó còn nhiều thứ dính vô mà chưa có hiểu hết.

chào bác . bác có thể giup em hieu cái truyen thong PC vs con pic16f84 ko ạ, vì con này ko có chân tx, rx ạ. nếu có phần cứng thì tốt quá ạ. em đang điều khiển động cơ bước dùng con pic16f84 các góc nhập từ máy tính ạ . em viết bằng asm thanks bác nhiu :)