串口只能接收,不能发送??

嵌入式乌托邦 2013-05-06 03:19:05
用的芯片是AT91SAM9x35,有6路串口,usart0-usart3,uart0-uart1,在/arch/arm/mach-at91/board-sam9x5ek.c下面默认开启了usart0,对应ttyS1,ttyS0为DBGU口。
static void __init ek_map_io(void)
{
/* Initialize processor and DBGU */
cm_map_io();

/* USART0 on ttyS1. (Rx, Tx) */
at91_register_uart(AT91SAM9X5_ID_USART0, 1, 0);
}
我想再开启一路串口使用,就在上面添加了
static void __init ek_map_io(void)
{
/* Initialize processor and DBGU */
cm_map_io();

/* USART0 on ttyS1. (Rx, Tx) */
at91_register_uart(AT91SAM9X5_ID_USART0, 1, 0);
at91_register_uart(AT91SAM9X5_ID_USART2, 2, 0);
}
这样应该会出现ttyS0,ttyS1,ttyS2的,重新烧写,启动,打印信息中出现了
atmel_usart.0: ttyS0 at MMIO 0xfefff200 (irq = 1) is a ATMEL_SERIAL
atmel_usart.1: ttyS1 at MMIO 0xf801c000 (irq = 5) is a ATMEL_SERIAL
atmel_usart.2: ttyS2 at MMIO 0xf8024000 (irq = 7) is a ATMEL_SERIAL
#cat /proc/tty/driver/atmel_serial
0: uart:ATMEL_SERIAL mmio:0xFEFFF200 irq:1 tx:1026 rx:39 RTS|CTS|DTR|DSR|CD|RI
1: uart:ATMEL_SERIAL mmio:0xF801C000 irq:5 tx:0 rx:0 DSR|CD|RI
2: uart:ATMEL_SERIAL mmio:0xF8024000 irq:7 tx:0 rx:0 CTS|DSR|CD|RI
貌似出现了设备节点,下面进行读写操作,用串口调试助手查看收发数据。
发送部分程序:
fd = open("/dev/ttyS2",O_RDWR | O_NOCTTY );
if(fd == -1)
{
perror("Can't Open Serial Port\n");
return -1;
}
printf("Open Serial OK!\n");
tcgetattr(fd,&opt);//获取当前配置
cfmakeraw(&opt);
cfsetispeed(&opt,B9600); /*设置输入输出为9600Bps*/
cfsetospeed(&opt,B9600);
tcsetattr(fd, TCSANOW, &opt);//设置新配置
retv=write(fd,sbuf,lenth);
if(retv==-1)
{
perror("retv write 1\n");
}
printf("The number of send data is:%d\n",retv);
close(fd)<0;
接收程序,和上面差不多。
操作新生成的ttyS2,就是发送不出数据,但可以接收数据。用同样的测试程序操作ttyS1,既能发数据也能收数据,这是怎么回事?
网上看到说要这样写:at91_register_uart(AT91SAM9X5_ID_USART2, 2, ATMEL_UART_RTS|ATMEL_UART_CTS);
但还是一样问题,求大神指点下!

...全文
2578 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
xijian1224 2013-10-15
  • 打赏
  • 举报
回复
我现在也遇到了这个问题,按楼主的方法还是不能解决,请问yangchaofeng001解决了吗?
还我紫霞 2013-05-28
  • 打赏
  • 举报
回复
为什么我变了后添加的串口还是不行呢?没有数据
嵌入式乌托邦 2013-05-07
  • 打赏
  • 举报
回复
解决了!在初始化时有这么个函数 void __init at91_add_device_serial(void) { int i; for (i = 0; i < ATMEL_MAX_UART; i++) { if (at91_usarts[i]) { #if defined(CONFIG_AT_HDMAC) || defined(CONFIG_AT_HDMAC_MODULE) int peripheral_id = platform_get_irq(at91_usarts[i], 0); struct atmel_uart_data *pdata = at91_usarts[i]->dev.platform_data; if (pdata->use_dma_tx) { struct at_dma_slave *atslave; atslave = kzalloc(sizeof(struct at_dma_slave), GFP_KERNEL); /* DMA slave channel configuration */ if (peripheral_id == AT91SAM9X5_ID_USART0 || peripheral_id == AT91SAM9X5_ID_USART1 || peripheral_id == AT91SAM9X5_ID_UART0) atslave->dma_dev = &at_hdmac0_device.dev; else atslave->dma_dev = &at_hdmac1_device.dev; atslave->reg_width = DW_DMA_SLAVE_WIDTH_8BIT; atslave->cfg = ATC_FIFOCFG_HALFFIFO | ATC_SRC_H2SEL_SW | ATC_DST_H2SEL_HW | (AT_DMA_ID_USART0_TX << 4); /*ATC_DST_PER(peripheral_id);*/ pdata->dma_tx_slave = atslave; } #endif platform_device_register(at91_usarts[i]); } } if (!atmel_default_console_device) printk(KERN_INFO "AT91: No default serial console defined.\n"); } 中间有用到DMA传输,所以我就将上面的 static struct atmel_uart_data usart2_data = { .use_dma_tx = 1, .use_dma_rx = 1, }; 改为了 static struct atmel_uart_data usart2_data = { .use_dma_tx = 0, .use_dma_rx = 0, }; 最后可以正常通讯了,收发都可以。
liujwcool1 2013-05-07
  • 打赏
  • 举报
回复
检查下tx脚的复用模式是否设置为串口了
嵌入式乌托邦 2013-05-07
  • 打赏
  • 举报
回复
ttyS2的tx没发数据时一直是高电平,在发送数据时没有跳变;OK的ttyS1的tx没发数据时也是一直高电平,发送数据时电平有跳变。
DDR2013 2013-05-06
  • 打赏
  • 举报
回复
tx应该是高电平,然后用示波器量下,看看有没有波形输出
cclutpk 2013-05-06
  • 打赏
  • 举报
回复
ttys2的tx电平是高还是低?
嵌入式乌托邦 2013-05-06
  • 打赏
  • 举报
回复
这是内核中usart2的引脚配置,没错啊。 static struct resource usart2_resources[] = { [0] = { .start = AT91SAM9X5_BASE_USART2, .end = AT91SAM9X5_BASE_USART2 + SZ_16K - 1, .flags = IORESOURCE_MEM, }, [1] = { .start = AT91SAM9X5_ID_USART2, .end = AT91SAM9X5_ID_USART2, .flags = IORESOURCE_IRQ, }, }; static struct atmel_uart_data usart2_data = { .use_dma_tx = 1, .use_dma_rx = 1, }; static u64 usart2_dmamask = DMA_BIT_MASK(32); static struct platform_device at91sam9x5_usart2_device = { .name = "atmel_usart", .id = 3, .dev = { .dma_mask = &usart2_dmamask, .coherent_dma_mask = DMA_BIT_MASK(32), .platform_data = &usart2_data, }, .resource = usart2_resources, .num_resources = ARRAY_SIZE(usart2_resources), }; static inline void configure_usart2_pins(unsigned pins) { at91_set_A_periph(AT91_PIN_PA7, 1); /* TXD2 */ at91_set_A_periph(AT91_PIN_PA8, 0); /* RXD2 */ if (pins & ATMEL_UART_RTS) at91_set_B_periph(AT91_PIN_PB0, 0); /* RTS2 */ if (pins & ATMEL_UART_CTS) at91_set_B_periph(AT91_PIN_PB1, 0); /* CTS2 */ } void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) { struct platform_device *pdev; switch (id) { case 0: /* DBGU */ pdev = &at91sam9x5_dbgu_device; configure_dbgu_pins(); at91_clock_associate("mck", &pdev->dev, "usart"); break; case AT91SAM9X5_ID_USART0: pdev = &at91sam9x5_usart0_device; configure_usart0_pins(pins); at91_clock_associate("usart0_clk", &pdev->dev, "usart"); break; case AT91SAM9X5_ID_USART1: pdev = &at91sam9x5_usart1_device; configure_usart1_pins(pins); at91_clock_associate("usart1_clk", &pdev->dev, "usart"); break; case AT91SAM9X5_ID_USART2: pdev = &at91sam9x5_usart2_device; configure_usart2_pins(pins); at91_clock_associate("usart2_clk", &pdev->dev, "usart"); break; case AT91SAM9X5_ID_USART3: pdev = &at91sam9x5_usart3_device; configure_usart3_pins(pins); at91_clock_associate("usart3_clk", &pdev->dev, "usart"); break; case AT91SAM9X5_ID_UART0: pdev = &at91sam9x5_uart0_device; configure_uart0_pins(pins); at91_clock_associate("uart0_clk", &pdev->dev, "usart"); break; case AT91SAM9X5_ID_UART1: pdev = &at91sam9x5_uart1_device; configure_uart1_pins(pins); at91_clock_associate("uart1_clk", &pdev->dev, "usart"); break; default: return; } pdev->id = portnr; /* update to mapped ID */ if (portnr < ATMEL_MAX_UART) at91_usarts[portnr] = pdev; } ttyS2的tx电平在发送数据时没有跳变,ttyS1的tx电平在发送数据时有跳变。
cclutpk 2013-05-06
  • 打赏
  • 举报
回复
后面修改的做法不对,因为你的uart2没有使用流控 建议检查一下uart2的tx脚的配置对不对,同时检查tx电平

21,595

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 驱动开发/核心开发
社区管理员
  • 驱动开发/核心开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧