/* ECE 476 Final Project
* Austin S. Lu & Albert Ren
* asl45 awr8
*/
#include <mega32.h>
#include <stdio.h>
#include <stdlib.h> //for ltoa
#include <delay.h>
#asm
.equ __lcd_port=0x15
#endasm
#include <lcd.h>
//Bruce's definitions
#define begin {
#define end }
//Define the states for the state machine
#define Command 0
#define DecodeCommand 1
#define Send 2
#define button_release 3
#define hold 4
#define Receive 5
int state = 0;
//Define the commands we support
//MODE 2 iPod Remote Functions
#define play 0x01
#define volup 0x02
#define voldown 0x04
#define skipfwd 0x08
#define skipback 0x10
#define menu 0x40
#define select 0x80
//MODE 4 Advanced Remote
#define type 0x12
#define name 0x14
#define current 0x1e
#define title 0x20
#define artist 0x22
#define album 0x24
//MODE 4 Send Commands
#define Switch 0
#define GetTrack 1
#define UseTrack 2
#define SwitchtoMode2 3
#define SendPlay 4
//Information on the Apple Accessory Protocol can be found at
// http://ipodlinux.org/Apple_Accessory_Protocol
//Here are some variables that we'll need
char mstime = 0;
char header1 = 0xff;
char header2 = 0x55;
char length;
char mode=0x02;
char command[2];
int checksum;
int index = 0;
int debouncecounter = 0;
char lastpress = 0;
char press = 0;
int timeout = 0;
unsigned long currentsong;
int param_length = 0;
//Here are the flags we're using
char validcommand = 0;
char commandtype = 0;
char stopflag = 0;
char releaseflag = 0;
char transmitdone_flag = 0;
char mode4flag = 0;
unsigned char switchmode[16] = {0xff, 0x55, 0x03, 0x00, 0x01, 0x04, 0xF8, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
unsigned char switchback[16] = {0xff, 0x55, 0x03, 0x00, 0x01, 0x02, 0xFA, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
unsigned char currenttrackcommand[16] = {0xff, 0x55, 0x03, 0x04, 0x00, 0x1E, 0xDB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
int tempchecksum;
unsigned char t_buffer_temp[16];
//For LCD displays
unsigned char lcdbuffer[50];
unsigned int lcdbufferlength = 16;
unsigned int lcdstart = 0;
int lcdtime = 0;
char hold_timer = 0;
int timeoutcounter = 0;
int failurecount = 0;
int mode4sequence = 0;
//variables we use for transmitting
unsigned char t_index; //current string index
unsigned char t_buffer[16]; //output string
unsigned char t_ready; //flag for transmit done
unsigned char t_char; //current character
//RXC ISR variables
unsigned char r_index=0; //current string index
unsigned char r_buffer[128]; //input string
unsigned char r_ready; //flag for receive done
unsigned char r_char; //current character
unsigned char r_checksum; //received checksum
unsigned char prev_char = 0;
unsigned char start_checksum = 0;
unsigned char r_length = 0xF5;
//Functions we use
void initialize(void);
void puts_int(void);
void buttons (void);
void gets_int(void);
void lcd_scroll(void);
//timer 0 overflow ISR
interrupt [TIM0_COMP] void timer0_overflow(void)
begin
mstime++;
lcdtime ++;
end
//UART xmit-empty ISR
//TRANSMITS LSB FIRST (Little Endian is stupid!)
//http://en.wikipedia.org/wiki/Serial_port
interrupt [USART_DRE] void uart_send(void)
{
t_index++;
t_char = t_buffer[t_index];
if(t_char == (char)checksum){//at this point, we know what the end is
UDR = t_char;
stopflag = 1;
stopflag = 0;
UCSRB.5=0; //kill isr
t_ready=1; //transmit done
checksum = 0;
}
else {UDR = t_char;} //send the char
}
//UART character-ready ISR
interrupt [USART_RXC] void uart_rec(void)
begin
r_char=UDR; //get a char
//build the input string
//iPod takes the form of 0xFF 0x55 Data Checksum
//We are assuming idle high, so we should check for 0x55 instead
if((r_char == (char)(r_checksum & 0xff)) && ((r_index-3)==r_length)) {
r_ready=1; //signal cmd processor
UCSRB.7=0; //stop rec ISR
start_checksum = 0;
}
if(start_checksum == 1) {
r_checksum = r_checksum - r_char;
}
if(r_char == 0x55 && prev_char == 0xff) {
start_checksum = 1;
r_checksum = 0x100;
}
r_buffer[r_index]=r_char;
if(r_index == 2) //Make the length so!
r_length = r_buffer[r_index];
r_index++;
prev_char = r_char;
end
void main(void)
begin
int k, temp, ReturnToSender;
unsigned char songnumber;
//State machine updates every ms for now
initialize();
while(1)
begin
if(lcdtime >= 300)
{
lcdtime = 0;
lcd_scroll();
}
if(mstime)
begin
buttons();
mstime = 0;
switch (state)
begin
case(Command):
//check if there's a command. If so, we will decode it
mode4sequence = Switch;
timeoutcounter = 0;
failurecount = 0;
if(validcommand == 1)
begin
validcommand = 0;
state = DecodeCommand;
end
if((releaseflag == 1) && (validcommand == 0) && (mode == 0x02)) //the button was released
begin
releaseflag = 0;
state = button_release;
end
break;
case(DecodeCommand):
//We must decode the command! If statements galore!
t_buffer[0] = header1; //0xff
t_buffer[1] = header2; //0x55
if((mode == 0x02) || (commandtype == current))
{
length = 0x03;
}
else
begin
length = 7; //Otherwise length is 7 bytes, cause it's a mode 4 command
end
t_buffer[2] = length;
t_buffer[3] = mode;
if(mode == 0x04)
{
mode4flag = 1;
}
t_buffer[4] = 0x00; //Beginning of command
if(commandtype == play)
t_buffer[5] = play;
if(commandtype == volup)
t_buffer[5] = volup;
if(commandtype == voldown)
t_buffer[5] = voldown;
if(commandtype == skipfwd)
t_buffer[5] = skipfwd;
if(commandtype == skipback)
t_buffer[5] = skipback;
if(commandtype == album)
t_buffer[5] = album;
if(commandtype == title)
t_buffer[5] = title;
if (commandtype == artist)
t_buffer[5] = artist;
if((mode == 0x04) && (commandtype != current)) //We need to send ipod the current song
begin
t_buffer[6] = (currentsong >> 24) & 0xff ; //& with 0xFF cause we're cautious people!
t_buffer[7] = (currentsong >> 16) & 0xff;
t_buffer[8] = (currentsong >> 8) & 0xff;
t_buffer[9] = currentsong & 0xff;
param_length = 4; //Mode 4 and Mode 2 have different lengths
end
for (index = 2; index < 6 + param_length; index ++) { //for checksum
checksum = checksum + t_buffer[index];
}
checksum = (0x100 - checksum & 0xff);
t_buffer[6+param_length] = (char) checksum & 0xff; //as a char */
param_length = 0; //We always reset to Mode 2 commands
state = Send;
break;
case(Send):
stopflag = 0;
timeoutcounter = 0;
老外写的用MCU控制IPOD的代码



标题中的“老外写的用MCU控制IPOD的代码”揭示了这是一个关于微控制器(MCU)与苹果公司的便携式音乐播放器iPod之间的交互项目。这个项目的核心是利用MCU,具体来说是MICROCHIP品牌的单片机,通过串行通信接口来控制iPod的各种功能,如播放、暂停以及切换上下首歌曲。 我们要理解MCU在其中的角色。MCU(Microcontroller Unit)是一种集成化的微处理器,包含CPU、内存和外围接口,用于控制电子设备。在这个项目中,MCU作为主控单元,负责接收和处理来自外部的指令,然后向iPod发送相应的控制信号。 描述中提到的“通过串口控制IPOD”指的是利用串行通信接口进行数据交换。串行通信是一种数据传输方式,一次只传输一位二进制数据,通常包括RS-232、UART、SPI或I2C等协议。在这个项目中,很可能是使用UART(通用异步收发传输器)因为其简单且广泛应用于嵌入式系统中。 实现这样的控制功能,我们需要以下步骤: 1. **硬件连接**:MCU需要通过物理接口(如UART的TX/RX引脚)连接到iPod的相应控制端口。这可能需要查阅iPod的公开文档或者第三方适配器的设计资料。 2. **协议解析**:理解iPod与MCU之间通信的协议。这可能涉及特定的命令集和响应格式,需要对iPod的控制协议有深入理解。 3. **软件编程**:编写MCU端的控制程序,如finalproject.c文件所示。这个程序应该包含初始化串口、解析输入指令、生成控制命令并发送到iPod的功能。 4. **指令编码**:为实现播放、暂停、上下曲等功能,MCU需要根据iPod的协议将这些操作编码为特定的控制命令。 5. **错误处理**:程序需要包含错误检测和处理机制,确保在通信出现问题时能够恢复正常。 6. **用户界面**:虽然描述中没有提及,但通常还需要一个简单的用户界面(如按钮或触摸屏)来输入控制指令,这些输入会被MCU读取并转换成对应的iPod控制命令。 7. **调试与测试**:对整个系统进行测试和调试,确保所有功能正常运行,并且在不同条件下都能稳定工作。 这个项目涵盖了微控制器编程、串行通信、硬件接口设计、协议解析和嵌入式系统开发等多个IT领域的知识点。通过这个项目,开发者不仅可以提升对MCU应用的理解,还能掌握与外部设备通信的关键技术。


















- 1

- 粉丝: 0
- 资源: 18
我的内容管理 展开
我的资源 快来上传第一个资源
我的收益
登录查看自己的收益我的积分 登录查看自己的积分
我的C币 登录后查看C币余额
我的收藏
我的下载
下载帮助


最新资源



- 1
- 2
前往页